/* -*-mode:java; c-basic-offset:2; -*- */
/* WeirdX - Guess.
 *
 * Copyright (C) 1999-2004 JCraft, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package com.jcraft.weirdx;

import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.xwww.html.DefaultHTMLFactory;
import org.xwww.requests.CreateWindowRequest;
import org.xwww.requests.XRequest;
import org.xwww.requests.XRequestDispatcher;

class Window extends Drawable {

    static Logger log = Logger.getLogger(Window.class);

    static Object LOCK = Window.class;

    private static final int CWBackPixmap = (1 << 0);

    private static final int CWBackPixel = (1 << 1);

    private static final int CWBorderPixmap = (1 << 2);

    private static final int CWBorderPixel = (1 << 3);

    private static final int CWBitGravity = (1 << 4);

    private static final int CWWinGravity = (1 << 5);

    private static final int CWBackingStore = (1 << 6);

    private static final int CWBackingPlanes = (1 << 7);

    private static final int CWBackingPixel = (1 << 8);

    private static final int CWOverrideRedirect = (1 << 9);

    private static final int CWSaveUnder = (1 << 10);

    private static final int CWEventMask = (1 << 11);

    private static final int CWDontPropagate = (1 << 12);

    private static final int CWColormap = (1 << 13);

    private static final int CWCursor = (1 << 14);

    private static final int CWX = (1 << 0);

    private static final int CWY = (1 << 1);

    private static final int CWWidth = (1 << 2);

    private static final int CWHeight = (1 << 3);

    private static final int CWBorderWidth = (1 << 4);

    private static final int CWSibling = (1 << 5);

    private static final int CWStackMode = (1 << 6);

    private static final int ChangeMask = (CWX | CWY | CWWidth | CWHeight);

    private static final int IllegalInputOnlyConfigureMask = CWBorderWidth;

    private static final int CopyFromParent = 0;

    private static final int InputOutput = 1;

    private static final int InputOnly = 2;

    private static final int NotifyNormal = 0;

    private static final int NotifyGrab = 1;

    private static final int NotifyUngrab = 2;

    private static final int NotifyWhileGrabbed = 3;

    private static final int NotifyAncestor = 0;

    private static final int NotifyVirtual = 1;

    private static final int NotifyInferior = 2;

    private static final int NotifyNonlinear = 3;

    private static final int NotifyNonlinearVirtual = 4;

    private static final int NotifyPointer = 5;

    private static final int NotifyPointerRoot = 6;

    private static final int NotifyDetailNone = 7;

    private static final int RevertToNone = 0;

    private static final int RevertToPointerRoot = 1;

    private static final int RevertToParent = 2;

    private static final int NoneWin = 0;

    private static final int PointerRootWin = 1;

    private static final int PointerRoot = 1;

    private static final int FollowKeyboard = 3;

    private static final int FollowKeyboardWin = 3;

    private static final int AsyncPointer = 0;

    private static final int SyncPointer = 1;

    private static final int ReplayPointer = 2;

    private static final int AsyncKeyboard = 3;

    private static final int SyncKeyboard = 4;

    private static final int ReplayKeyboard = 5;

    private static final int AsyncBoth = 6;

    private static final int SyncBoth = 7;

    private static final int GrabModeSync = 0;

    private static final int GrabModeAsync = 1;

    private static final int GrabSuccess = 0;

    private static final int AlreadyGrabbed = 1;

    private static final int GrabInvalidTime = 2;

    private static final int GrabNotViewable = 3;

    private static final int GrabFrozen = 4;

    static int deltaSaveUndersViewable = 0;

    static int defaultBackingStore = 0;

    static int AnyModifier = (1 << 15);

    static int AnyKey = 0;

    private static final int Above = 0;

    private static final int Below = 1;

    private static final int TopIf = 2;

    private static final int BottomIf = 3;

    private static final int Opposite = 4;

    private static final int Restack = 0;

    private static final int Move = 1;

    private static final int Resize = 2;

    private static final int Reborder = 3;

    private static final int NOT_GRABBED = 0;

    private static final int THAWED = 1;

    private static final int THAWED_BOTH = 2;

    private static final int FREEZE_NEXT_EVENT = 3;

    private static final int FREEZE_BOTH_NEXT_EVENT = 4;

    private static final int FROZEN = 5;

    private static final int FROZEN_NO_EVENT = 5;

    private static final int FROZEN_WITH_EVENT = 6;

    private static final int THAW_OTHERS = 7;

    private static final int backgroundStateOffset = 0;

    private static final int backgroundState = (3 << 0);

    private static final int ParentRelative = (1 << backgroundStateOffset);

    private static final int BackgroundPixel = (2 << backgroundStateOffset);

    private static final int BackgroundPixmap = (3 << backgroundStateOffset);

    private static final int borderIsPixelOffset = 2;

    private static final int borderIsPixel = (1 << borderIsPixelOffset);

    private static final int cursorIsNoneOffset = 3;

    private static final int cursorIsNone = (1 << cursorIsNoneOffset);

    private static final int backingStoreOffset = 4;

    private static final int backingStore = (3 << backingStoreOffset);

    private static final int saveUnderOffset = 6;

    private static final int saveUnder = (1 << saveUnderOffset);

    private static final int DIXsaveUnderOffset = 7;

    private static final int DIXsaveUnder = (1 << DIXsaveUnderOffset);

    private static final int bitGravityOffset = 8;

    private static final int bitGravity = (15 << bitGravityOffset);

    private static final int ForgetGravity = 0;

    private static final int winGravityOffset = 12;

    private static final int winGravity = (15 << winGravityOffset);

    private static final int ForegetGravity = 0;

    private static final int NorthWestGravity = 1;

    private static final int NorthGravity = 2;

    private static final int NorthEastGravity = 3;

    private static final int WestGravity = 4;

    private static final int CenterGravity = 5;

    private static final int EastGravity = 6;

    private static final int SouthWestGravity = 7;

    private static final int SouthGravity = 8;

    private static final int SouthEastGravity = 9;

    private static final int StaticGravity = 10;

    private static final int UnmapGravity = 0;

    private static final int overrideRedirectOffset = 16;

    private static final int overrideRedirect = (1 << overrideRedirectOffset);

    private static final int visibilityOffset = 17;

    private static final int visibility = (3 << visibilityOffset);

    private static final int VisibilityUnobscured = 0;

    private static final int VisibilityPartiallyObscured = 1;

    private static final int VisibilityFullyObscured = 2;

    private static final int VisibilityNotViewable = 3;

    private static final int mappedOffset = 19;

    private static final int mapped = (1 << mappedOffset);

    private static final int realizedOffset = 20;

    private static final int realized = (1 << realizedOffset);

    private static final int viewableOffset = 21;

    private static final int viewable = (1 << viewableOffset);

    private static final int dontPropagateOffset = 22;

    private static final int dontPropagate = (7 << dontPropagateOffset);

    private static final int forcedBSOffset = 25;

    private static final int forcedBS = (1 << forcedBSOffset);

    private static final int DBE_FRONT_BUFFER = 1;

    private static final int DBE_BACK_BUFFER = 0;

    private static final int dstBufferOffset = 26;

    private static final int dstBuffer = (1 << dstBufferOffset);

    private static final int srcBufferOffset = 27;

    private static final int srcBuffer = (1 << srcBufferOffset);

    private static final int PlaceOnTop = 0;

    private static final int PlaceOnBottom = 1;

    private static final int RaiseLowest = 0;

    private static final int LowerHighest = 1;

    static final Focus focus = new Focus();

    static Sprite sprite = new Sprite();

    static int spriteTraceGood = 1;

    static Window[] spriteTrace = new Window[10];

    static Point gpoint = new Point();

    static Grab grab = null;

    static Class dDXWindow = null;
    static {
        try {
            dDXWindow = Class.forName("com.jcraft.weirdx.DDXWindowImp");
        } catch (Exception e) {
            System.err.println(e);
        }
    }

    static void installDDXWindow(String name) {
        Class c = null;
        try {
            if (name.startsWith("com.jcraft.weirdx."))
                c = Class.forName(name);
        } catch (Exception e) {
            System.err.println(e);
        }
        if (c != null)
            dDXWindow = c;
    }

    Client client;

    Window parent;

    Window nextSib;

    Window prevSib;

    Window firstChild;

    Window lastChild;

    Point origin = new Point();

    int borderWidth;

    int deliverableEvents;

    int eventMask;

    Pix background = new Pix();

    Pix border = new Pix();

    WindowOpt optional;

    int attr;

    DDXWindow ddxwindow;

    int frame_x = -1;

    int frame_y = -1;

    int frame_width = -1;

    int frame_height = -1;

    Window(int id) {
        super(id, RT_WINDOW);
    }

    Window(int wid, Window prnt, int x, int y, int width, int height,
            int bwidth, int clss, byte depth, Client client, int visual, int msk)
            throws IOException {

        this(wid);
        WindowOpt opt;
        this.client = client;
        this.parent = prnt;
        screen = prnt.screen;

        if (clss == CopyFromParent)
            clss = prnt.clss;
        this.clss = clss;

        if ((clss != InputOutput) && (clss != InputOnly)) {
            client.errorValue = clss;
            client.errorReason = 2; // BadValue;
            return;
        }

        if ((clss != InputOnly) && (prnt.clss == InputOnly)) {
            client.errorValue = clss;
            client.errorReason = 8; // BadMatch;
            return;
        }
        if ((clss == InputOnly) && ((bwidth != 0) || (depth != 0))) {
            client.errorValue = 0;
            client.errorReason = 8; // BadMatch;
            return;
        }

        if ((clss == InputOutput) && (depth == 0)) {
            depth = prnt.depth;
        }

        opt = prnt.optional;
        if (opt == null) {
            opt = prnt.findOptional().optional;
        }
        if (visual == CopyFromParent) {
            visual = opt.visual;
        }
        if ((visual != opt.visual) || (depth != prnt.depth)) {
            boolean foo = false;
            Depth pdepth;
            for (int i = 0; i < screen.depth.length; i++) {
                pdepth = screen.depth[i];
                if (depth == pdepth.depth || depth == 0) {
                    if (pdepth.visual != null) {
                        for (int j = 0; j < pdepth.visual.length; j++) {
                            if (visual == pdepth.visual[j].id) {
                                foo = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (!foo) {
                client.errorValue = 0;
                client.errorReason = 8; // BadMatch;
                return;
            }
        }
        if (((msk & (CWBorderPixmap | CWBorderPixel)) == 0)
                && (clss != InputOnly) && (depth != prnt.depth)) {
            client.errorValue = 0;
            client.errorReason = 8; // BadMatch;
            return;
        }

        this.depth = depth;
        if (depth == prnt.depth) {
            this.bitsPerPixel = prnt.bitsPerPixel;
        } else {
            int ii = 0;
            while (ii < Format.format.length) {
                if (Format.format[ii].depth == screen.rootDepth)
                    break;
                ii++;
            }
            if (ii == Format.format.length) {
                // ???
                ii = 0;
            }
            this.bitsPerPixel = Format.format[ii].bpp;
        }

        this.type = prnt.type;
        if (clss == InputOnly)
            this.type = UNDRAWABLE_WINDOW;

        setDefault();

        if (visual != opt.visual) {
            makeOptional();
            this.optional.visual = visual;
            this.optional.colormap = screen.defaultColormap;
        }
        this.borderWidth = bwidth;
        attr &= ~backgroundState;
        attr &= ~borderIsPixel;
        attr |= (prnt.attr & borderIsPixel);

        this.border = prnt.border.dup();

        if ((attr & borderIsPixel) == 0) {
            this.border.pixmap.ref();
        }
        this.origin.x = (short) (x + bwidth);
        this.origin.y = (short) (y + bwidth);
        this.width = width;
        this.height = height;
        this.x = (short) (prnt.x + x + bwidth);
        this.y = (short) (prnt.y + y + bwidth);

        synchronized (LOCK) {
            this.nextSib = prnt.firstChild;
            if (prnt.firstChild != null)
                prnt.firstChild.prevSib = this;
            else
                prnt.lastChild = this;
            prnt.firstChild = this;
        }

        if ((msk & CWEventMask) == 0) {
            recalculateDeliverableEvents();
        }

        msk &= 0x7fff;
        if (msk != 0) {
            changeAttr(client, msk);
        }

        if (client.errorReason != 0) {
            this.delete();
            return;
        }

        if ((msk & CWBackingStore) != 0 && (defaultBackingStore != 0)) {
            attr &= ~backingStore;
            attr |= (defaultBackingStore << backingStoreOffset);
            attr |= forcedBS;
        }

        // ddxwindow=new DDXWindow();
        try {
            ddxwindow = (DDXWindow) dDXWindow.newInstance();
        } catch (Exception e) {
            System.err.println(e); /* ddxwindow=new DDXWindow(); */
        }
        ddxwindow.init(this);

        try {
            if (screen.windowmode != WeirdX.InBrowser && prnt == screen.root) {
                final java.awt.Window frame = getFrame();
                /*
                 * if(frame instanceof JFrame){
                 * ((JFrame)frame).setJMenuBar(null);
                 * ((JFrame)frame).getContentPane().setLayout(null);
                 * ((JFrame)frame).setResizable(false); } else
                 */if (frame instanceof Frame) {
                    ((Frame) frame).setMenuBar(null);
                    ((Frame) frame).setResizable(true);
                }

                ddxwindow.setLocation(0, 0);

                // if(frame instanceof JFrame){
                // ((JFrame)frame).getContentPane().add((java.awt.Component)ddxwindow);
                // }
                // else{
                frame.add((java.awt.Component) ddxwindow);
                // }

                frame.pack();
                Insets insets = frame.getInsets();
                /*
                 * frame.setSize(this.width+this.borderWidth*2+
                 * insets.left+insets.right, this.height+this.borderWidth*2+
                 * insets.bottom+insets.top);
                 */
                frame.setLocation(this.origin.x - this.borderWidth
                        + parent.borderWidth, this.origin.y - this.borderWidth
                        + parent.borderWidth);

                if (frame instanceof Frame) {
                    addWindowListener((java.awt.Frame) frame);
                    addComponentListener((java.awt.Frame) frame);
                }
            } else {
                ddxwindow.setLocation(origin.x - borderWidth
                        + parent.borderWidth, origin.y - borderWidth
                        + parent.borderWidth);
                prnt.ddxwindow.add((java.awt.Component) ddxwindow, 0);
            }
            if ((attr & cursorIsNone) == 0) {
                Cursor cur = getCursor();
                if (cur != null) {
                    ddxwindow.setCursor(cur.cursor);
                }
            }
            if (bwidth > 0) {
                ddxwindow.setBorderPixmap(border.pixmap);
            }
        } catch (Exception ee) {
            // System.out.println("error: Window?? "+ee);
        }

        if (prnt.subSend()) {
            client.cevent.mkCreateNotify(prnt.id, id, x, y, width, height,
                    borderWidth, (attr & overrideRedirect) != 0 ? 0 : 1);
            prnt.sendEvent(client.cevent, 1, null);
        }
    }

    private final void changeAttr(Client c, int vmask) throws IOException {
        int foo;
        boolean borderRelative = false;
        int index = 0;
        int mask = vmask;
        IO io = c.client;

        while (mask != 0 && c.length != 0) {
            index = lowbit(mask);
            mask &= ~index;
            c.length--;
            switch (index) {
            case CWBackPixmap:
                foo = io.readInt();
                if ((attr & backgroundState) == ParentRelative)
                    borderRelative = true;
                if (foo == 0) {
                    if ((attr & backgroundState) == BackgroundPixmap) {
                        if (background.pixmap == null) {
                            // System.err.println("BackPixmap: error!!");
                        } else {
                            try {
                                background.pixmap.delete();
                            } catch (Exception e) {
                            }
                            background.pixmap = null;
                        }
                    }
                    attr = attr & (~backgroundState);
                } else if (foo == ParentRelative) {
                    if (parent != null && depth != parent.depth) {
                    }
                    if ((attr & backgroundState) == BackgroundPixmap) {
                        if (background.pixmap == null) {
                            // System.err.println("BackPixmap: error!!");
                        } else {
                            try {
                                background.pixmap.delete();
                            } catch (Exception e) {
                            }
                            background.pixmap = null;
                        }
                    }
                    if (parent == null) {
                    } else {
                        attr = (attr & ~backgroundState)
                                | (backgroundState & ParentRelative);
                    }
                    borderRelative = true;
                } else {
                    Pixmap pixmap = (Pixmap) Resource.lookupIDByType(foo,
                            Resource.RT_PIXMAP);
                    if (pixmap != null) {
                        if (pixmap.depth != depth || pixmap.screen != screen) {
                            // System.err.println("error!!");
                        }
                        if ((attr & backgroundState) == BackgroundPixmap) {
                            if (background.pixmap == null) {
                                // System.err.println("BackPixmap: error!!");
                            } else {
                                try {
                                    background.pixmap.delete();
                                } catch (Exception e) {
                                }
                                background.pixmap = null;
                            }
                        }
                        attr = (attr & ~backgroundState)
                                | (backgroundState & BackgroundPixmap);
                        background.pixmap = pixmap;
                        background.img = pixmap.getImage(this);

                        pixmap.ref();
                    } else {
                        // System.err.println("error!!");
                    }
                }
                break;
            case CWBackPixel:
                foo = io.readInt();
                if ((attr & backgroundState) == ParentRelative) {
                    borderRelative = true;
                }
                if ((attr & backgroundState) == BackgroundPixmap) {
                    if (background.pixmap == null) {
                        // System.err.println("BackPixel: error!!");
                    } else {
                        try {
                            background.pixmap.delete();
                        } catch (Exception e) {
                        }
                        background.pixmap = null;
                    }
                }
                attr &= ~backgroundState;
                attr |= BackgroundPixel;
                background.pixel = foo;
                break;
            case CWBorderPixmap:
                foo = io.readInt();
                if (foo == CopyFromParent) {
                    if (parent == null || depth != parent.depth) {
                        // System.err.println("err!!");
                    }
                    if ((attr & borderIsPixel) == 0) {
                        if (border.pixmap == null) {
                            // System.err.println("BorderPixmap: error!!");
                        } else {
                            try {
                                border.pixmap.delete();
                            } catch (Exception e) {
                            }
                            border.pixmap = null;
                        }
                    }

                    border = parent.border.dup();
                    attr &= ~borderIsPixel;
                    attr |= (parent.attr & borderIsPixel);
                    if ((attr & borderIsPixel) != 0) {
                    } else {
                        if (border.pixmap == null) {
                            // System.err.println("BorderPixmap: error!!!");
                        } else {
                            border.pixmap.ref();
                        }
                    }
                } else {
                    Pixmap pixmap = (Pixmap) Resource.lookupIDByType(foo,
                            Resource.RT_PIXMAP);
                    if (pixmap != null) {
                        if ((pixmap.depth != depth)
                                || (pixmap.screen != screen)) {
                            // System.err.println("error!!");
                        }
                        if ((attr & borderIsPixel) == 0) {
                            if (border.pixmap == null) {
                                // System.err.println("BorderPixmap: error!!");
                            } else {
                                try {
                                    border.pixmap.delete();
                                } catch (Exception e) {
                                }
                                border.pixmap = null;
                            }
                        }
                        attr &= ~borderIsPixel;
                        border.pixmap = pixmap;
                        pixmap.ref();
                    } else {
                        // System.err.println("error!!");
                    }
                }
                break;
            case CWBorderPixel:
                foo = io.readInt();
                if ((attr & borderIsPixel) == 0) {
                    if (border.pixmap == null) {
                        // System.err.println("BorderPixmap: error!!");
                    } else {
                        try {
                            border.pixmap.delete();
                        } catch (Exception e) {
                        }
                        border.pixmap = null;
                    }
                }
                attr |= borderIsPixel;
                border.pixel = foo;
                break;
            case CWBitGravity:
                foo = io.readInt();
                foo &= 0xff;

                if (foo > StaticGravity) {
                    // System.err.println("error!!");
                }
                attr &= ~bitGravity;
                attr |= (foo << bitGravityOffset);

                break;
            case CWWinGravity:
                foo = io.readInt();
                foo &= 0xff;

                if (foo > StaticGravity) {
                    // System.err.println("error!!");
                }
                attr &= ~winGravity;
                attr |= (foo << winGravityOffset);

                break;
            case CWBackingStore:
                foo = io.readInt();
                foo &= 0xff;

                if (foo != 0 && foo != 1 && foo != 2) {
                    // System.err.println("error!!");
                }
                attr &= ~backingStore;
                attr |= (foo << backingStoreOffset);
                attr &= ~forcedBS;
                break;
            case CWBackingPlanes:
                foo = io.readInt();
                if (optional != null || foo != ~0) {
                    makeOptional();
                    optional.backingBitPlanes = foo;
                }
                break;
            case CWBackingPixel:
                foo = io.readInt();
                if (optional != null || foo != 0) {
                    makeOptional();
                    optional.backingPixel = foo;
                }
                break;
            case CWOverrideRedirect:
                foo = io.readInt();
                foo &= 0xff;
                if ((foo != 0) && (foo != 1)) {
                    // System.err.println("error!");
                }
                // if(foo==1){ attr|=overrideRedirect;}
                attr &= ~overrideRedirect;
                attr |= (foo << overrideRedirectOffset);
                break;
            case CWSaveUnder:
                foo = io.readInt();
                foo &= 0xff;

                if ((foo != 0) && (foo != 1)) {
                    // System.err.println("error !!");
                }
                if (parent != null
                        && ((attr & saveUnder) != (foo << saveUnderOffset))
                        && (attr & viewable) != 0) {
                    if ((attr & saveUnder) != 0)
                        deltaSaveUndersViewable--;
                    else
                        deltaSaveUndersViewable++;
                    attr &= ~saveUnder;
                    attr |= (foo << saveUnderOffset);
                    if (firstChild != null) {
                    } else {
                    }
                } else {
                    attr &= ~saveUnder;
                    attr |= (foo << saveUnderOffset);
                }
                break;
            case CWEventMask:
                foo = io.readInt();
                setEventMask(c, foo);
                break;
            case CWDontPropagate:
                foo = io.readInt();
                eventSuppress(foo);
                break;
            case CWColormap:
                foo = io.readInt();
                if (foo == 0) { // CopyFromParent
                    if (parent != null
                            && (optional == null || optional.visual == (parent.optional != null ? parent.optional.visual
                                    : parent.findOptional().optional.visual))) {
                        foo = parent.getColormap().id;
                    }
                }
                if (foo == 0) {
                    c.errorReason = 8; // BadMatch
                    c.errorValue = foo;
                    return;
                }
                Colormap cmap = (Colormap) Resource.lookupIDByType(foo,
                        Resource.RT_COLORMAP);
                if (cmap == null) {
                    c.errorReason = 12; // BadColor
                    c.errorValue = foo;
                    return;
                }
                makeOptional();
                optional.colormap = cmap;
                c.cevent.mkColormapNotify(id, foo, 1, 1);
                sendEvent(c.cevent, 1, null);
                break;
            case CWCursor:
                foo = io.readInt();
                Cursor cur = null,
                old = null;
                if (foo == 0) {
                    if (this == screen.root) {
                        cur = Cursor.rootCursor;
                    } else {
                        cur = null;
                    }
                } else {
                    cur = (Cursor) Resource.lookupIDByType(foo,
                            Resource.RT_CURSOR);
                    if (cur == null) {
                        c.errorReason = 6; // BadCursor
                        c.errorValue = foo;
                        return;
                    }
                }
                if (cur != getCursor()) {
                    if (cur == null) {
                        attr |= cursorIsNone;
                        if (optional != null) {
                            old = optional.cursor;
                            optional.cursor = null;
                        }
                    } else {
                        makeOptional();
                        old = optional.cursor;
                        optional.cursor = cur;
                        attr &= ~cursorIsNone;
                        if (ddxwindow != null) {
                            ddxwindow.setCursor(cur.cursor);
                        }
                    }
                }
                break;
            default:
                c.length++;
                c.errorValue = vmask;
                c.errorReason = 2; // BadValue;
            }
            // try{HexStream.err.hexInt(attr); System.out.println(" <-attr");}
            // catch(Exception e){}
            if (c.errorReason != 0) {
                return;
            }
        }

        if (c.length != 0) {
            c.errorValue = vmask;
            c.errorReason = 2; // BadValue;
        }
        return;
    }

    private int eventSuppress(int mask) {
        int i = 0, free;
        if ((attr & dontPropagate) != 0) {
            DontPropagate.refc[(attr & dontPropagate) >> dontPropagateOffset]--;
        }
        if (mask != 0) {
            i = DontPropagate.store(mask);
        }
        if (i != 0 || mask == 0) {
            attr &= ~dontPropagate;
            attr |= (i << dontPropagateOffset);
            if (i != 0) {
                DontPropagate.refc[i]++;
            }
            if (optional != null) {
                optional.dontPropagateMask = mask;
            }
        } else {
            makeOptional();
            attr &= ~dontPropagate;
            optional.dontPropagateMask = mask;
        }
        recalculateDeliverableEvents();
        return 0;
    }

    static final void reqCirculateWindow(Client c) throws IOException {
        int n, foo;
        IO io = c.client;

        int direction = c.data;
        foo = io.readInt();

        c.length -= 2;

        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }
        if (direction != RaiseLowest && direction != LowerHighest) {
            c.errorValue = direction;
            c.errorReason = 2; // BadValue
            return;
        }

        synchronized (LOCK) {
            Window win = null;
            Window first = w.firstChild;
            if (direction == RaiseLowest) {
                win = w.lastChild;
                while ((win != null) && !(win.isMapped())) {
                    win = win.prevSib;
                }
                if (win == null)
                    return;
            } else {
                win = first;
                while ((win != null) && !(win.isMapped())) {
                    win = win.nextSib;
                }
                if (win == null)
                    return;
            }
            c.cevent.mkCirculateRequest(w.id, win.id,
                    (direction == RaiseLowest) ? PlaceOnTop : PlaceOnBottom);
            if (w.redirectSend()) {
                if (w.sendEvent(c.cevent, 1, Event.SubstructureRedirectMask, c) == 1)
                    return;
            }
            c.cevent.mkCirculateNotify(win.id, w.id, w.id,
                    (direction == RaiseLowest) ? PlaceOnTop : PlaceOnBottom);
            win.sendEvent(c.cevent, 1, null);
            win.reflectStackChange((direction == RaiseLowest) ? first : null);
        }
        return;
    }

    static final void reqAllowEvents(Client c) throws IOException {
        int foo, mode;
        IO io = c.client;
        mode = c.data;
        foo = io.readInt();
        switch (mode) {
        case AsyncPointer:
            break;
        case SyncPointer:
            break;
        case ReplayPointer:
            break;
        case AsyncKeyboard:
            break;
        case SyncKeyboard:
            break;
        case ReplayKeyboard:
            break;
        case AsyncBoth:
            break;
        case SyncBoth:
            break;
        default:
        }
        Window.sprite.hot.state = 0;
    }

    static final void reqGetMotionEvents(Client c) throws IOException {
        int foo, n;
        IO io = c.client;

        foo = io.readInt();
        Window w = c.lookupWindow(foo);
        foo = io.readInt();
        foo = io.readInt();
        c.length -= 4;
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        synchronized (io) {
            io.writeByte(1);
            io.writePad(1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeInt(0);
            io.writePad(20);
            io.flush();
        }
    }

    static final void reqTranslateCoordinates(Client c) throws IOException {
        int foo;
        IO io = c.client;
        foo = io.readInt();
        Window srcw = c.lookupWindow(foo);
        if (srcw == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow
        }
        foo = io.readInt();
        Window dstw = c.lookupWindow(foo);
        if (dstw == null && c.errorReason == 0) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow
        }
        int x = io.readShort();
        int y = io.readShort();
        c.length -= 4;
        if (c.errorReason != 0) {
            return;
        }

        int gx = x + srcw.x;
        int gy = y + srcw.y;

        int child = 0;

        synchronized (LOCK) {
            Window win = dstw.firstChild;
            while (win != null) {
                if (((win.attr & mapped) != 0) && win.contains(gx, gy)) {
                    child = win.id;
                    win = null;
                } else {
                    win = win.nextSib;
                }
            }
        }

        x = gx - dstw.x;
        y = gy - dstw.y;

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(1); // same screen
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeInt(child);
            io.writeShort(x);
            io.writeShort(y);
            io.writePad(16);
            io.flush();
        }
    }

    static final void reqGetScreenSaver(Client c) throws IOException {
        int foo, n;
        IO io = c.client;

        synchronized (io) {
            io.writeByte(1);
            io.writePad(1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeShort(600);
            io.writeShort(600);
            io.writeByte((byte) 1);
            io.writeByte((byte) 1);
            io.writePad(18);
            io.flush();
        }
    }

    static final void reqQueryBestSize(Client c) throws IOException {
        int foo, clss;
        IO io = c.client;
        clss = c.data;
        foo = io.readInt();
        c.length -= 2;
        Drawable d = c.lookupDrawable(foo);
        if ((clss != 0 /* CursorShape */) && (clss != 1 /* TileShape */)
                && (clss != 2 /* StippleShape */)) {
            c.errorValue = clss;
            c.errorReason = 2; // BadValue;
            return;
        }
        if (d == null) {
            c.errorValue = foo;
            c.errorReason = 9; // BadDrawable;
            return;
        }
        foo = io.readShort();
        foo = io.readShort();

        synchronized (io) {
            io.writeByte(1);
            io.writePad(1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeShort(32);
            io.writeShort(32);
            io.writePad(20);
            io.flush();
        }
    }

    static final void reqDestroySubwindows(Client c) throws IOException {
        int foo;
        IO io = c.client;
        foo = io.readInt();
        c.length -= 2;
        Window w = c.lookupWindow(foo);

        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }
        synchronized (LOCK) {
            w.unmapSubwindows(c);
            while (w.lastChild != null) {
                Resource.freeResource(w.lastChild.id, Resource.RT_NONE);
            }
        }
    }

    void makeBackgroundTile(int xx, int yy, int w, int h) {
        Window win = this;
        int i = (attr & backgroundState);
        if (i == ParentRelative) {
            win = parent;
            if (win == null)
                return;
            i = (win.attr & backgroundState);
        }

        if (i == BackgroundPixmap && win.background.pixmap != null) {
            Image img = win.background.img;
            if (img == null)
                return;
            if (!win.ddxwindow.isVisible())
                return;
            Graphics g = null;
            java.awt.Shape tmp = null;
            if (xx != 0 || yy != 0 || w != width || h != height) {
                g = getGraphics();
                tmp = g.getClip();
                g.clipRect(xx, yy, w, h);
            }
            if (win == this) {
                ddxwindow.fillImage(img, win.background.pixmap.width,
                        win.background.pixmap.height);
            } else {
                ddxwindow.fillImage(img, win.background.pixmap.width,
                        win.background.pixmap.height, origin.x - borderWidth,
                        origin.y - borderWidth);
            }
            if (g != null) {
                if (tmp == null) {
                    g.setClip(0, 0, width, height);
                } else {
                    g.setClip(tmp);
                }
            }
        } else if (i == BackgroundPixel) {
            Colormap cmap = win.getColormap();
            ddxwindow.setBackground(cmap.getColor(win.background.pixel), xx,
                    yy, w, h);
        }
    }

    private void free() {
        SaveSet.delete(this);
        Selection.delete(this);
        try {
            deleteEvent(true);
        } catch (Exception e) {
            // System.out.println(e);
        }

        try {
            deleteProperties();
        } catch (Exception e) {
            // System.out.println(e);
        }

        origin = null;
        if ((attr & backgroundState) == BackgroundPixmap) {
            if (background.pixmap == null) {
                // System.err.println("free: error!!");
            } else {
                try {
                    background.pixmap.delete();
                } catch (Exception e) {
                }
                background.pixmap = null;
            }
        }
        background = null;
        if ((attr & borderIsPixel) == 0) {
            if (border.pixmap == null) {
                // System.err.println("free: error!!!");
            } else {
                try {
                    border.pixmap.delete();
                } catch (Exception e) {
                }
                border.pixmap = null;
            }
        }
        border = null;
        optional = null;

        try {
            ddxwindow.delete();
        } catch (Exception e) {
        }

        if (hasFrame()) {
            delFrame();
        }
    }

    private void deleteEvent(boolean freeResources) throws IOException {
        Grab passive;
        if (Window.grab != null && Window.grab.window == this) {
            Window.grab.deactivatePointerGrab();
        }
        if ((id == focus.win) && (parent != null)) {
            int focusEventMode = NotifyNormal;
            switch (focus.revert) {
            case RevertToNone:
                doFocusEvents(null, id, 0, focusEventMode);
                focus.win = 0;
                focus.window = null;
                focus.traceGood = 0;
                break;
            case RevertToParent:
                Window win = this;
                do {
                    win = win.parent;
                    focus.traceGood--;
                } while (win != null && !win.isRealized());

                int p = (win == null) ? 0 : win.id;
                doFocusEvents(null, id, p, focusEventMode);
                focus.win = p;
                focus.window = win;
                focus.revert = RevertToNone;
                break;
            case RevertToPointerRoot:
                doFocusEvents(null, id, PointerRootWin, focusEventMode);
                focus.win = PointerRootWin;
                focus.window = null;
                focus.traceGood = 0;
                break;
            }
        }

        if (freeResources) {
            if ((attr & dontPropagate) != 0) {
                DontPropagate.refc[(attr & dontPropagate) >> dontPropagateOffset]--;
            }
            OtherClients oc;
            while ((oc = getOtherClients()) != null) {
                Resource.freeResource(oc.id, Resource.RT_NONE);
            }
            while ((passive = getPassiveGrabs()) != null) {
                Resource.freeResource(passive.id, Resource.RT_NONE);
            }
        }
    }

    private void deleteProperties() throws IOException {

        Property pProp, pNextProp;
        pProp = getProperty();
        while (pProp != null) {
            client.cevent.mkPropertyNotify(id, pProp.propertyName, (int) System
                    .currentTimeMillis(), 1 // Property.PropertyDelete
                    );
            sendEvent(client.cevent, 1, null);
            pNextProp = pProp.next;
            pProp.data = null;
            pProp = pNextProp;
        }
    }

    private void crushTree() throws IOException {
        Window child, sib, cparent;
        if ((child = firstChild) == null)
            return;
        while (true) {
            if (child.firstChild != null) {
                child = child.firstChild;
                continue;
            }
            while (true) {
                cparent = child.parent;
                if (child.substrSend()) {
                    Event event = new Event();
                    event.mkDestroyNotify(child.id, child.id);
                    try {
                        child.sendEvent(event, 1, null);
                    } catch (Exception e) {
                        // System.out.println("crush: exception -> "+e);
                    }
                }
                try {
                    Resource.freeResource(child.id, Resource.RT_WINDOW);
                } catch (Exception e) {
                    // System.out.println("crush: exception -> "+e);
                }

                sib = child.nextSib;
                child.attr &= ~viewable;
                if ((child.attr & realized) != 0) {
                    child.attr &= ~realized;
                    child.attr |= visibility;
                    child.ddxwindow.setVisible(false);

                    if (screen.windowmode != WeirdX.InBrowser
                            && child.hasFrame()) {
                        child.getFrame().setVisible(false);
                    }
                }

                try {
                    child.free();
                } catch (Exception e) {
                    // System.out.println("crush: exception -> "+e);
                }

                if ((child = sib) != null)
                    break;

                child = cparent;
                child.firstChild = null;
                child.lastChild = null;
                if (child == this)
                    return;
            }
        }
    }

    void delete() throws IOException {
        synchronized (LOCK) {
            try {
                unmapWindow(false);
            } catch (Exception e) {
            }
            try {
                crushTree();
            } catch (Exception e) {
            }

            if (id != 0 && parent != null && substrSend()) {
                Event event = new Event();
                event.mkDestroyNotify(id, id);
                try {
                    sendEvent(event, 1, null);
                } catch (Exception e) {
                }
            }

            if (parent != null) {
                if (parent.firstChild == this)
                    parent.firstChild = nextSib;
                if (parent.lastChild == this)
                    parent.lastChild = prevSib;
                if (nextSib != null)
                    nextSib.prevSib = prevSib;
                if (prevSib != null)
                    prevSib.nextSib = nextSib;
            }
            parent = null;
            nextSib = null;
            prevSib = null;
            firstChild = null;
            lastChild = null;
            prevSib = null;

            try {
                free();
            } catch (Exception e) {
            }
        }
    }

    static final void reqDestroyWindow(Client c) throws IOException {
        int foo;
        IO io = c.client;
        foo = io.readInt();
        c.length -= 2;
        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        if (w.parent != null) {
            Resource.freeResource(w.id, Resource.RT_NONE);
        }
    }

    static final void reqSendEvent(Client c) throws IOException {
        Window win;
        Window effectiveFocus = null; // only set if dest==InputFocus
        int foo;
        IO io = c.client;
        int prop = c.data;
        int dest = io.readInt();
        int emask = io.readInt();
        byte[] bb = new byte[32];
        io.readByte(bb, 0, 32);
        c.length = 0;
        Event event = new Event(bb);
        if (c.swap) {
            event.swap();
        }

        if (dest == 0/* PointerWindow */) {
            win = sprite.win;
        } else {
            win = c.lookupWindow(dest);
        }

        if (win == null) {
            c.errorValue = dest;
            c.errorReason = 3; // BadWindow;
            return;
        }

        if ((prop != 0) && (prop != 1)) {
            c.errorValue = prop;
            c.errorReason = 2; // BadValue;
            return;
        }

        event.setType((byte) (event.getType() | 0x80));
        if (prop != 0) {
            for (; win != null; win = win.parent) {
                if (win.sendEvent(event, 1, emask, null, 0) != 0)
                    return;
                emask &= ~win.getDontPropagateMask();
                if (emask == 0)
                    break;
            }
        } else {
            win.sendEvent(event, 1, emask, null, 0);
        }

        return;
    }

    static final void reqGetPointerMapping(Client c) throws IOException {
        int foo, n;
        IO io = c.client;

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(0);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writePad(24);
            io.flush();
        }
    }

    static final void reqSetPointerMapping(Client c) throws IOException {
        int foo, n;
        IO io = c.client;
        foo = c.data;
        n = c.length;
        n--;
        while (n != 0) {
            foo = io.readInt();
            n--;
        }

        synchronized (io) {
            io.writeByte(1);
            io.writeByte((byte) 1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writePad(24);
            io.flush();
        }
    }

    static final void reqGetPointerControl(Client c) throws IOException {
        int foo, n;
        IO io = c.client;

        synchronized (io) {
            io.writeByte(1);
            io.writePad(1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeShort(2);
            io.writeShort(1);
            io.writeShort(4);
            io.writePad(18);
            io.flush();
        }
    }

    static final void reqQueryPointer(Client c) throws IOException {
        int n, foo;
        IO io = c.client;
        foo = io.readInt();
        c.length -= 2;
        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        int hx = Window.sprite.hot.x;
        int hy = Window.sprite.hot.y;

        Window child = null;
        synchronized (LOCK) {
            for (Window ww = Window.sprite.win; ww != null; ww = ww.parent) {
                if (ww.parent == w) {
                    child = ww;
                    break;
                }
            }

            if (child != null) {
                if (!child.contains(hx, hy)) {
                    sprite.win = xy2Window(hx, hy, null);
                    child = null;
                    for (Window ww = sprite.win; ww != null; ww = ww.parent) {
                        if (ww.parent == w) {
                            child = ww;
                            break;
                        }
                    }
                }
            }
        }

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(1);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeInt(w.screen.rootId);

            io.writeInt((child == null ? 0 : child.id));
            io.writeShort(hx);
            io.writeShort(hy);
            io.writeShort(hx - w.x);
            io.writeShort(hy - w.y);
            io.writeShort(Window.sprite.hot.state);
            // io.writeShort(0); // ?????????
            io.writePad(6);
            io.flush();
        }
    }

    static final void reqGetGeometry(Client c) throws IOException {
        IO io = c.client;
        int foo = io.readInt();

        Drawable d = c.lookupDrawable(foo);
        c.length -= 2;
        if (d == null) {
            c.errorValue = foo;
            c.errorReason = 9; // BadValue;
            return;
        }

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(d.depth);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeInt(d.screen.rootId);

            if ((d.type == UNDRAWABLE_WINDOW)
                    || ((d.type == DRAWABLE_WINDOW) && foo == d.id)) {
                Window w = (Window) d;
                io.writeShort(w.origin.x - w.borderWidth);
                io.writeShort(w.origin.y - w.borderWidth);
                io.writeShort(w.width);
                io.writeShort(w.height);
                io.writeShort(w.borderWidth);
            } else {
                io.writeShort(0);
                io.writeShort(0);
                io.writeShort(d.width);
                io.writeShort(d.height);
                io.writeShort(0);
            }
            io.writePad(10);
            io.flush();
        }
    }

    static final void reqChangeWindowAttributes(Client c) throws IOException {
        int foo;
        IO io = c.client;

        int wid = io.readInt();
        int mask = io.readInt();

        c.length -= 3;

        Window w = c.lookupWindow(wid);
        if (w == null) {
            c.errorValue = wid;
            c.errorReason = 3; // BadWindow;
            return;
        }

        mask &= 0x7fff;
        if (mask != 0) {
            w.changeAttr(c, mask);
        }

        if (c.errorReason != 0) {
            return;
        }

        if ((mask & CWBorderPixmap) != 0 || (mask & CWBorderPixel) != 0) {
            w.ddxwindow.setBorderPixmap(w.border.pixmap);
        }
    }

    static final void reqUngrabPointer(Client c) throws IOException {
        int foo, n;
        IO io = c.client;
        foo = io.readInt();
        if ((Window.grab != null) && Window.grab.sameClient(c)) {
            Window.grab.deactivatePointerGrab();
        }
    }

    static final void reqUngrabButton(Client c) throws IOException {
        int foo;
        int button, mod;
        IO io = c.client;

        button = c.data;
        foo = io.readInt();

        c.length -= 2;
        Window gw = c.lookupWindow(foo);
        if (gw == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        mod = io.readShort();
        io.readPad(2);
        c.length--;
        Grab grab = Grab.createGrab(c, gw, 0, 0, 0, 0, mod, 4, button, null);

        if (!grab.deletePassiveGrabFromList()) {
            c.errorReason = 11; // BadAlloc
        }
    }

    static final void reqGrabButton(Client c) throws IOException {
        int foo, n;
        int pmode, kmode, oe, emask, button, mod;
        IO io = c.client;

        oe = c.data;
        if (oe != 0 && oe != 1) {
        }

        foo = io.readInt();
        Window gw = c.lookupWindow(foo);
        if (gw == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
        }
        emask = io.readShort();
        if ((emask & ~Event.PointerGrabMask) != 0) {
        }

        pmode = io.readByte();
        if ((pmode != GrabModeSync) && (pmode != GrabModeAsync)) {
        }

        kmode = io.readByte();
        if ((kmode != GrabModeSync) && (kmode != GrabModeAsync)) {
        }

        foo = io.readInt();
        Window cto = null;
        if (foo != 0) {
            cto = c.lookupWindow(foo);
        }

        foo = io.readInt();
        button = io.readByte();
        io.readPad(1);
        mod = io.readShort();
        c.length -= 6;

        if (c.errorReason != 0) {
            return;
        }

        if (gw == null || cto == null) {
        }

        Grab grab = Grab.createGrab(c, gw, emask, oe, kmode, pmode, mod,
                Event.ButtonPress, button, cto);
        grab.addPassiveGrabToList();
    }

    static final void reqGrabPointer(Client c) throws IOException {
        int foo, n;
        int pmode, kmode, oe, emask, time;
        IO io = c.client;

        oe = c.data;
        if (oe != 0 && oe != 1) {
            c.errorValue = oe;
            c.errorReason = 2; // BadValue;
        }

        foo = io.readInt();
        Window gw = c.lookupWindow(foo);
        if (gw == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow
        }

        emask = io.readShort();
        if ((emask & ~Event.PointerGrabMask) != 0) {
            c.errorValue = emask;
            c.errorReason = 2; // BadValue;
        }

        pmode = io.readByte();
        if ((pmode != GrabModeSync) && (pmode != GrabModeAsync)) {
            c.errorValue = pmode;
            c.errorReason = 2; // BadValue
        }

        kmode = io.readByte();
        if ((kmode != GrabModeSync) && (kmode != GrabModeAsync)) {
            c.errorValue = kmode;
            c.errorReason = 2; // BadValue
        }

        foo = io.readInt();
        Window cto = null;
        if (foo != 0) {
            cto = c.lookupWindow(foo);
            if (cto == null) {
                c.errorValue = foo;
                c.errorReason = 3; // BadWindow
            }
        }

        foo = io.readInt();
        Cursor cur = null;
        if (foo != 0) {
            cur = (Cursor) Resource.lookupIDByType(foo, Resource.RT_CURSOR);
            if (cur == null) {
                c.errorValue = foo;
                c.errorReason = 6; // BadCursor
            }
        }

        time = io.readInt();

        c.length -= 6;

        if (c.errorReason != 0) {
            return;
        }

        int res = 0;
        if (Window.grab != null && c != Window.grab.getClient()) {
            res = AlreadyGrabbed;
        } else if ((gw.attr & realized) == 0
                || (cto != null && !((cto.attr & realized) != 0 && (cto.width != 0 || cto.height != 0)))) {
            res = GrabNotViewable;
        } else {
            Grab grab = new Grab(Resource.fakeClientId(c));
            grab.set(c.clientAsMask, gw, oe, emask, kmode, pmode, cto);
            grab.activatePointerGrab((int) System.currentTimeMillis(), true);
            res = GrabSuccess;
        }

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(res);
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writePad(24);
            io.flush();
        }
    }

    static final void reqCreateWindow(Client c) throws IOException {

    	log.debug("Init CreateWindow.");
    	
        byte depth;
        int parentid, x, y, width, height, bwidth, clss;
        int wid, visual;
        int mask;
        IO io = c.client;

        depth = (byte) c.data;

        
        XRequest xreq = XRequestDispatcher.createRequest( 1 );
        xreq.captureDataFromStream( io );

        // Xwww integration
        wid 		= xreq.findParameter("wid").getValueInt();
        parentid 	= xreq.findParameter("parent").getValueInt();
        x 			= xreq.findParameter("x").getValueInt();
        y 			= xreq.findParameter("y").getValueInt();
        width 		= xreq.findParameter("width").getValueInt();
        height 		= xreq.findParameter("height").getValueInt();
        bwidth 		= xreq.findParameter("border-width").getValueInt();
        clss 		= xreq.findParameter("class").getValueInt();
        visual 		= xreq.findParameter("visual").getValueInt();
        mask 		= xreq.findParameter("value-mask").getValueInt();
        
        
//        wid 		= io.readInt();
//        parentid 	= io.readInt();
//        x 			= io.readShort();
//        y 			= io.readShort();
//        width 		= io.readShort();
//        height 		= io.readShort();
//        bwidth 		= io.readShort();
//        clss 		= io.readShort();
//        visual 		= io.readInt();
//        mask 		= io.readInt();

        Window prnt = c.lookupWindow(parentid);
        c.length -= 8;

        if (prnt == null) {
            c.errorValue = parentid;
            c.errorReason = 3; // BadWindow;
        }

        if ((width == 0 || height == 0) && c.errorReason == 0) {
            c.errorValue = 0;
            c.errorReason = 2; // BadValue;
        }

        Window w = null;
        if (c.errorReason == 0) {
            w = new Window(wid, prnt, x, y, width, height, bwidth, clss, depth,
                    c, visual, mask);
        }

        // Create html
        String html = xreq.createHTML();
        DefaultHTMLFactory kk = new DefaultHTMLFactory();
        kk.writeHTML( html );
        

        if (c.errorReason != 0) {
        	log.debug("Error");
            return;
        }
        Resource.add(w);
    }

    int sendEvent(Event event, int count, int filter, Grab grab, int mskidx)
            throws IOException {
        int deliveries = 0, nondeliveries = 0;
        int attempt;
        Client c = null;
        int deliveryMask = 0;
        int type = event.getType();

        if ((filter == Event.CantBeFiltered)
                || ((type & Event.EXTENSION_EVENT_BASE) == 0)) {
            if ((filter != Event.CantBeFiltered)
                    && (((getOtherEventMask() | eventMask) & filter) == 0)) {
                return 0;
            }
            attempt = 1;
            try {
                attempt = client.sendEvent(event, count, eventMask, filter,
                        grab);
            } catch (Exception e) {
            }

            if (attempt != 0) {
                if (attempt > 0) {
                    deliveries++;
                    c = client;
                    deliveryMask = eventMask;
                } else
                    nondeliveries--;
            }
        }

        Clients other;
        if (filter != Event.CantBeFiltered) {
            if ((type & Event.EXTENSION_EVENT_BASE) != 0) {
                OtherInputMasks inputMasks;

                inputMasks = (optional == null ? null
                        : optional.otherInputMasks);
                if ((inputMasks == null)
                        || ((inputMasks.inputEvents[mskidx] & filter) == 0)) {
                    return 0;
                }
                other = (Clients) (inputMasks.inputClients);
            } else {
                other = (Clients) (optional == null ? null
                        : optional.otherClients);
            }

            for (; other != null; other = (OtherClients) other.next) {
                attempt = 1;
                try {
                    if (other.getClient() != null) {
                        int mask = (other instanceof OtherClients) ? ((OtherClients) other).mask
                                : ((InputClients) other).mask[mskidx];
                        attempt = other.getClient().sendEvent(event, count,
                                mask, filter, grab);
                    } else {
                        attempt = 0;
                    }
                } catch (Exception e) {
                }

                if (attempt != 0) {
                    if (attempt > 0) {
                        deliveries++;
                        c = other.getClient();
                        deliveryMask = ((other instanceof OtherClients) ? ((OtherClients) other).mask
                                : ((InputClients) other).mask[mskidx]);
                    } else
                        nondeliveries--;
                }
            }
        }

        if (c == null) {
            if (deliveries != 0) {
                return deliveries;
            }
            return nondeliveries;
        }

        if ((type == Event.ButtonPress) && (deliveries != 0) && (grab == null)) {
            grab = new Grab(Resource.fakeClientId(c));
            grab.set(c.clientAsMask, this,
                    (deliveryMask & Event.OwnerGrabButtonMask), deliveryMask,
                    GrabModeAsync, GrabModeAsync, null);
            grab.activatePointerGrab((int) System.currentTimeMillis(), true);
        }
        if (deliveries != 0)
            return deliveries;
        return nondeliveries;
    }

    int sendEvent(Event event, int count, Window otherParent)
            throws IOException {
        int filter;
        int deliveries;

        if (count == 0)
            return 0;

        filter = Event.filters[event.getType()];
        if (((filter & Event.SubstructureNotifyMask) != 0)
                && (event.getType() != Event.CreateNotify)) {
            event.putEvent(id);
        }

        if (filter != Event.StructureAndSubMask) {
            return sendEvent(event, count, filter, null, 0);
        }

        deliveries = sendEvent(event, count, Event.StructureNotifyMask, null, 0);

        if (parent != null) {
            event.putEvent(parent.id);
            deliveries += parent.sendEvent(event, count,
                    Event.SubstructureNotifyMask, null, 0);
            if (event.getType() == Event.ReparentNotify) {
                event.putEvent(otherParent.id);
                deliveries += otherParent.sendEvent(event, count,
                        Event.SubstructureNotifyMask, null, 0);
            }
        }
        return deliveries;
    }

    int sendEvent(Event event, int count, int filter, Client c)
            throws IOException {
        if ((eventMask & filter) != 0) {
            if (client == c)
                return 0;
            return client.sendEvent(event, count, eventMask, filter, null);
        }

        OtherClients other = (optional == null) ? null : optional.otherClients;
        for (; other != null; other = (OtherClients) other.next) {
            if ((other.mask & filter) != 0) {
                if (other.sameClient(c))
                    return 0;
                if (other.getClient() == null)
                    return 0;
                return other.getClient().sendEvent(event, count, other.mask,
                        filter, null);
            }
        }
        return 2;
    }

    private Window findOptional() {
        Window w = this;
        do {
            w = w.parent;
        } while (w.optional == null);
        return w;
    }

    private void setDefault() {
        prevSib = null;
        firstChild = null;
        lastChild = null;
        optional = null;
        attr = 0;

        attr |= cursorIsNone;

        attr |= visibility;
        attr |= (NorthWestGravity << winGravityOffset);

        eventMask = 0;
        attr |= (DBE_FRONT_BUFFER << srcBufferOffset);
        attr |= (DBE_FRONT_BUFFER << dstBufferOffset);
    }

    static final void reqUnmapSubWindows(Client c) throws IOException {
        int foo;
        IO io = c.client;
        foo = io.readInt();

        c.length -= 2;

        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }
        synchronized (LOCK) {
            w.unmapSubwindows(c);
        }
    }

    private void unmapSubwindows(Client c) throws IOException {
        if (firstChild == null)
            return;

        boolean wasRealized = (attr & realized) != 0;
        boolean wasViewable = (attr & viewable) != 0;
        boolean parentNotify = subSend();
        boolean anyMarked = false;

        for (Window child = lastChild; child != null; child = child.prevSib) {
            if ((child.attr & mapped) != 0) {
                if (parentNotify || child.strSend()) {
                    c.cevent.mkUnmapNotify(child.id, 0);
                    child.sendEvent(c.cevent, 1, null);
                }

                child.attr &= ~mapped;

                if ((child.attr & realized) != 0) {
                    child.unrealizeTree(false);
                }
            }
        }

        if (wasRealized) {
            restructured();
        }
    }

    static final void reqMapSubWindows(Client c) throws IOException {
        int foo;
        int mask;
        Window firstMapped = null;
        boolean anyMarked = false;

        IO io = c.client;

        foo = io.readInt();

        c.length -= 2;

        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        boolean parentRedirect = w.parent.redirectSend();
        boolean parentNotify = w.parent.subSend();

        synchronized (LOCK) {
            for (Window tmpw = w.firstChild; tmpw != null; tmpw = tmpw.nextSib) {
                if (w.screen.root != w && w.parent == null)
                    return;
                if ((tmpw.attr & mapped) == 0) {
                    if (parentRedirect && ((tmpw.attr & overrideRedirect) == 0)) {
                        c.cevent.mkMapRequest(w.id, tmpw.id);
                        if (w.sendEvent(c.cevent, 1,
                                Event.SubstructureRedirectMask, c) == 1) {
                            return;
                        }
                    }

                    tmpw.attr |= mapped;

                    if (parentNotify || w.strSend()) {
                        c.cevent
                                .mkMapNotify(
                                        tmpw.id,
                                        (tmpw.attr & overrideRedirect) >> overrideRedirectOffset);
                        tmpw.sendEvent(c.cevent, 1, null);
                    }
                    if (firstMapped == null)
                        firstMapped = tmpw;
                    if ((w.attr & realized) != 0) {
                        tmpw.realizeTree();
                    }
                }
            }

            if (firstMapped != null) {
                restructured();
            }
        }
    }

    static final void reqUnmapWindow(Client c) throws IOException {
        int foo;
        IO io = c.client;

        foo = io.readInt();

        c.length -= 2;

        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }
        synchronized (LOCK) {
            w.unmapWindow(false);
        }
    }

    private void unrealizeTree(boolean fromConfigure) {
        Window child = this;
        while (true) {
            if ((child.attr & realized) != 0) {
                child.attr &= ~realized;
                child.attr |= visibility; // VisibilityNotViewable
                child.ddxwindow.setVisible(false);

                if (screen.windowmode != WeirdX.InBrowser && child.hasFrame()) {
                    child.getFrame().setVisible(false);
                }

                try {
                    child.deleteEvent(false);
                } catch (Exception e) {
                    // System.out.println(e);
                }

                if ((child.attr & viewable) != 0) {
                    child.attr &= ~viewable;
                }
                if (child.firstChild != null) {
                    child = child.firstChild;
                    continue;
                }
            }
            while (child.nextSib == null && (child != this))
                child = child.parent;
            if (child == this)
                break;
            child = child.nextSib;
        }

        if (parent != null && borderWidth > 0) {
            parent.ddxwindow.draw(origin.x - borderWidth, origin.y
                    - borderWidth, width + 2 * borderWidth, height + 2
                    * borderWidth);
        }
    }

    private void realizeTree() throws IOException {
        Window child = this;
        while (true) {
            if ((child.attr & mapped) != 0) {
                child.attr |= realized;
                child.attr |= (child.clss == InputOutput) ? viewable : 0;
                child.attr &= ~visibility;
                child.attr |= (VisibilityUnobscured << visibilityOffset);
                if (screen.windowmode != WeirdX.InBrowser && child.hasFrame()) {
                    if ((0 <= child.x || 0 <= child.y
                            || 0 < (child.x + child.width) || 0 < (child.y + child.height))
                            && clss != 2) {
                        child.getFrame().setVisible(true);
                    }
                }
                child.ddxwindow.setVisible(true);
                child.ddxwindow.draw();
                if (((child.eventMask | child.getOtherEventMask()) & Event.VisibilityChangeMask) != 0) {
                    try {
                        child.sendVisibilityNotify();
                    } catch (Exception e) {
                    }
                }
                if (child.firstChild != null) {
                    child = child.firstChild;
                    continue;
                }
            }
            while (child.nextSib == null && (child != this)) {
                child = child.parent;
            }
            if (child == this) {
                return;
            }
            child = child.nextSib;
        }
    }

    private void unmapWindow(boolean fromConfigure) throws IOException {
        Screen screen = this.screen;
        boolean wasRealized = ((this.attr & realized) != 0);
        boolean wasViewable = ((this.attr & viewable) != 0);
        Window layerWin = this;

        if ((this.attr & mapped) == 0)
            return;

        if (parent == null)
            return;
        if (substrSend()) {
            Event event = new Event();
            event.mkUnmapNotify(id, (fromConfigure ? 1 : 0));
            try {
                sendEvent(event, 1, null);
            } catch (Exception e) {
            }
        }
        this.attr &= ~mapped;
        if (wasRealized) {
            this.unrealizeTree(fromConfigure);
        }

        if (wasRealized && !fromConfigure) {
            restructured();
        }
    }

    static final void reqMapWindow(Client c) throws IOException {
        int foo;
        IO io = c.client;

        foo = io.readInt();

        c.length -= 2;

        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }
        synchronized (LOCK) {
            w.mapWindow(c);
        }
    }

    void mapWindow(Client c) throws IOException {
        if ((this.attr & mapped) != 0)
            return;
        screen = this.screen;
        if (parent != null) {
            if (((this.attr & overrideRedirect) == 0)
                    && (parent.redirectSend())) {
                c.cevent.mkMapRequest(parent.id, id);
                int ii = parent.sendEvent(c.cevent, 1,
                        Event.SubstructureRedirectMask, c);
                if (ii == 1)
                    return;
            }
            this.attr |= mapped;
            if (substrSend()) {
                c.cevent.mkMapNotify(id,
                        (attr & overrideRedirect) >> overrideRedirectOffset);
                sendEvent(c.cevent, 1, null);
            }
            if ((this.parent.attr & realized) == 0)
                return;
            this.realizeTree();
            restructured();
        } else {
            this.attr |= mapped;
            this.attr |= realized;
            this.attr |= (this.clss == InputOutput) ? viewable : 0;
        }
    }

    static void restructured() throws IOException {
        try {
            checkMotion(null, null);
        } catch (Exception e) {
        }
    }

    static boolean checkMotion(Event e, Window hint) throws IOException {
        Window prevSpriteWin = sprite.win;
        sprite.win = xy2Window(sprite.hot.x, sprite.hot.y, hint);
        if (sprite.win != prevSpriteWin) {
            if (prevSpriteWin != null) {
                try {
                    enter_leaveEvent(prevSpriteWin, sprite.win, NotifyNormal);
                } catch (Exception ee) {
                    // System.out.println("checkmotion: execption -> "+ee);
                }
            }
            return false;
        }
        return true;
    }

    static void enter_leaveEvent(int type, int mode, int detail, Window win,
            int child) throws IOException {
        int mask;
        Grab grab = Window.grab;
        if (grab != null) {
            mask = (win == grab.window) ? grab.eventMask : 0;
            if ((grab.attr & grab.ownerEvents) != 0) {
                mask |= win.getEventMask(grab.getClient());
            }
        } else {
            mask = win.eventMask | win.getOtherEventMask();
        }

        if ((mask & Event.filters[type]) != 0) {
            Event event = new Event();
            event.fixUpEventFromWindow(win, 0, sprite.hot.x, sprite.hot.y,
                    false);
            int flags = 0;
            flags = (event.getSameScreen() != 0 ? 2 : 0);

            flags |= 1;

            mode = 0;
            event.mkPointer(type, detail, (int) System.currentTimeMillis(),
                    child, sprite.hot.x, sprite.hot.y, sprite.hot.state, mode,
                    flags);
            try {
                if (grab != null) {
                    if (grab.getClient() != null)
                        grab.getClient().sendEvent(event, 1, mask,
                                Event.filters[type], grab);
                } else {
                    win.sendEvent(event, 1, Event.filters[type], null, 0);
                }
            } catch (Exception e) {
                // System.out.println("enter_leaveEvent: exception -> "+e);
            }

        }
        if ((type == Event.EnterNotify)
                && ((mask & Event.KeymapStateMask) != 0)) {
            // KeymapNotify
        }
    }

    private int getEventMask(Client c) {
        if (c == null)
            return 0;
        if (client == c)
            return eventMask;
        if (client == null)
            return 0;
        for (OtherClients other = getOtherClients(); other != null; other = (OtherClients) other.next) {
            if (other.sameClient(c))
                return other.mask;
        }
        return 0;
    }

    private static void enterNotifies(Window ancestor, Window child, int mode,
            int detail) throws IOException {
        Window parent = child.parent;
        if (ancestor == parent)
            return;
        enterNotifies(ancestor, parent, mode, detail);
        enter_leaveEvent(Event.EnterNotify, mode, detail, parent, child.id);
    }

    private static void leaveNotifies(Window child, Window ancestor, int mode,
            int detail) throws IOException {
        if (ancestor == child)
            return;
        for (Window win = child.parent; win != ancestor; win = win.parent) {
            enter_leaveEvent(Event.LeaveNotify, mode, detail, win, child.id);
            child = win;
        }
    }

    static void enter_leaveEvent(Window fromWin, Window toWin, int mode)
            throws IOException {
        if (fromWin == toWin)
            return;
        if (fromWin.isParent(toWin)) {
            try {
                enter_leaveEvent(Event.LeaveNotify, mode, NotifyInferior,
                        fromWin, 0);
            } catch (Exception e) {
            }
            try {
                enterNotifies(fromWin, toWin, mode, NotifyVirtual);
            } catch (Exception e) {
            }
            try {
                enter_leaveEvent(Event.EnterNotify, mode, NotifyAncestor,
                        toWin, 0);
            } catch (Exception e) {
            }
        } else if (toWin.isParent(fromWin)) {
            try {
                enter_leaveEvent(Event.LeaveNotify, mode, NotifyAncestor,
                        fromWin, 0);
            } catch (Exception e) {
            }
            try {
                leaveNotifies(fromWin, toWin, mode, NotifyVirtual);
            } catch (Exception e) {
            }
            try {
                enter_leaveEvent(Event.EnterNotify, mode, NotifyInferior,
                        toWin, 0);
            } catch (Exception e) {
            }
        } else {
            Window common = toWin.commonAncestor(fromWin);
            try {
                enter_leaveEvent(Event.LeaveNotify, mode, NotifyNonlinear,
                        fromWin, 0);
            } catch (Exception e) {
            }
            try {
                leaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
            } catch (Exception e) {
            }
            try {
                enterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
            } catch (Exception e) {
            }
            try {
                enter_leaveEvent(Event.EnterNotify, mode, NotifyNonlinear,
                        toWin, 0);
            } catch (Exception e) {
            }
        }
    }

    boolean contains(int xx, int yy) {
        return ddxwindow.contains(xx - x - borderWidth, yy - y - borderWidth);
    }

    static Window xy2Window(int x, int y, Window hint) {
        if (hint != spriteTrace[spriteTraceGood - 1]) {
            spriteTraceGood = 1;
        }
        // else{ System.out.println("skip!!"); }

        Window win = spriteTrace[spriteTraceGood - 1];

        if (((win.attr & mapped) == 0) || !win.contains(x, y)) {
            win = spriteTrace[0];
            spriteTraceGood = 1;
        }

        win = win.firstChild;
        while (win != null) {
            if (((win.attr & mapped) != 0) && win.contains(x, y)) {
                if (spriteTraceGood >= spriteTrace.length) {
                    Window[] foo = new Window[spriteTrace.length + 10];
                    System
                            .arraycopy(spriteTrace, 0, foo, 0,
                                    spriteTrace.length);
                    spriteTrace = foo;
                }
                spriteTrace[spriteTraceGood++] = win;
                win = win.firstChild;
            } else {
                win = win.nextSib;
            }
        }

        return spriteTrace[spriteTraceGood - 1];
    }

    Cursor getCursor() {
        if (optional != null)
            return optional.cursor;
        Window p = findOptional();
        return p.optional.cursor;
    }

    private boolean redirectSend() {
        return ((eventMask | getOtherEventMask()) & Event.SubstructureRedirectMask) != 0;
    }

    private boolean subSend() {
        return ((eventMask | getOtherEventMask()) & Event.SubstructureNotifyMask) != 0;
    }

    private boolean strSend() {
        return ((eventMask | getOtherEventMask()) & Event.StructureNotifyMask) != 0;
    }

    private boolean substrSend() {
        return strSend() || parent.subSend();
    }

    void makeOptional() {
        if (optional != null)
            return;
        optional = new WindowOpt();
        optional.dontPropagateMask = DontPropagate.masks[(attr & dontPropagate) >> dontPropagateOffset];
        optional.otherEventMasks = 0;
        optional.backingBitPlanes = ~0L;
        optional.backingPixel = 0;
        if (parent != null) {
            WindowOpt parentOptional = findOptional().optional;
            optional.visual = parentOptional.visual;
            if ((attr & cursorIsNone) == 0) {
                optional.cursor = parentOptional.cursor;
            } else {
                optional.cursor = null;
            }
            optional.colormap = parentOptional.colormap;
        }
    }

    private void sendVisibilityNotify() throws IOException {
        Event event = new Event();
        event.mkVisibilityNotify(id, (attr & visibility) >> visibilityOffset);
        sendEvent(event, 1, null);
    }

    static final void reqQueryTree(Client c) throws IOException {
        int foo;
        Window prnt;
        Window w;
        int wid;
        int x, y, width, height, bwidth, clss;
        int visual;
        int mask;
        int rootId;
        IO io = c.client;
        wid = io.readInt();
        c.length -= 2;
        w = c.lookupWindow(wid);
        if (w == null) {
            c.errorValue = wid;
            c.errorReason = 3; // BadWindow;
            return;
        }

        synchronized (LOCK) {
            int numchild = 0;

            for (Window p = w.lastChild; p != null; p = p.prevSib) {
                numchild++;
            }

            synchronized (io) {
                io.writeByte(1);
                io.writePad(1);
                io.writeShort(c.seq);
                io.writeInt(numchild);
                io.writeInt(w.screen.rootId);

                if (w.parent != null)
                    io.writeInt(w.parent.id);
                else
                    io.writeInt(0);

                io.writeShort(numchild);
                io.writePad(14);

                if (0 < numchild) {
                    for (Window p = w.lastChild; p != null; p = p.prevSib) {
                        io.writeInt(p.id);
                    }
                }
                io.flush();
            }
        }
    }

    static final void reqSetInputFocus(Client c) throws IOException {
        int foo, n, reverto;
        IO io = c.client;

        reverto = c.data;
        foo = io.readInt();
        c.length -= 2;
        Window win = null;
        if (foo != 0 && foo != 1) {
            win = c.lookupWindow(foo);
            if (win == null) {
                c.errorValue = foo;
                c.errorReason = 3; // BadWindow;
                return;
            }
        }

        int time = io.readInt();
        c.length--;

        setInputFocus(c, foo, reverto, time, false);
    }

    static final void setInputFocus(Client c, int focusId, int revertTo,
            int time, boolean followOk) throws IOException {
        if ((revertTo != RevertToParent) && (revertTo != RevertToPointerRoot)
                && (revertTo != RevertToNone)) {
            c.errorValue = revertTo;
            c.errorReason = 2; // BadValue
            return;
        }

        int focusWin = 0;
        Window win = null;
        if ((focusId == 0) || (focusId == 1)) {
            focusWin = focusId;
        } else if ((win = c.lookupWindow(focusId)) == null) {
            c.errorValue = focusId;
            c.errorReason = 3;
            return;
        } else {
            if (!win.isRealized()) {
                c.errorReason = 8; // BadMatch
                return;
            }
            focusWin = focusId;
        }

        int mode = grab != null ? NotifyWhileGrabbed : NotifyNormal;
        doFocusEvents(c, focus.win, focusWin, mode);
        focus.time = time;
        focus.revert = revertTo;
        focus.win = focusWin;
        focus.window = win;

        if ((focusWin == 0) || (focusWin == 1)) {
            focus.traceGood = 0;
            if (focusWin == 1)
                Screen.screen[0].root.ddxwindow.requestFocus();
        } else {
            synchronized (LOCK) {
                win.ddxwindow.requestFocus();
                int depth = 0;
                for (Window tmpw = win; tmpw != null; tmpw = tmpw.parent)
                    depth++;
                if (depth > focus.traceSize) {
                    focus.traceSize = depth + 1;
                    focus.trace = new Window[focus.traceSize];
                }
                focus.traceGood = depth;
                depth--;
                for (Window tmpw = win; tmpw != null; tmpw = tmpw.parent, depth--) {
                    focus.trace[depth] = tmpw;
                }
            }
        }
    }

    static final void reqGetInputFocus(Client c) throws IOException {
        int foo;
        IO io = c.client;

        synchronized (io) {
            io.writeByte(1);
            io.writeByte(focus.revert); // revert-to
            io.writeShort(c.seq);
            io.writeInt(0);
            io.writeInt(focus.win); // focus
            io.writePad(20);
            io.flush();
        }
    }

    static final void reqGetWindowAttributes(Client c) throws IOException {
        int foo;
        IO io = c.client;

        foo = io.readInt();
        c.length -= 2;
        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow
            return;
        }

        synchronized (io) {
            io.writeByte(1);

            if ((w.attr & forcedBS) != 0 && (w.attr & backingStore) != 2)
                io.writeByte(0); // NotUseful
            else
                io.writeByte((w.attr & backingStore) >> backingStoreOffset);

            io.writeShort(c.seq);
            io.writeInt(3);
            io.writeInt(w.getVisual());
            io.writeShort(w.clss);
            io.writeByte((w.attr & bitGravity) >> bitGravityOffset);
            io.writeByte((w.attr & winGravity) >> winGravityOffset);
            io.writeInt(w.getBackingBitPlanes());
            io.writeInt(w.getBackingPixel());
            io.writeByte((w.attr & saveUnder) >> saveUnderOffset);

            if (w.getColormapId() == 0)
                io.writeByte(0);
            else
                io.writeByte(Colormap.isMapInstalled(w.getColormapId(), w));

            if ((w.attr & mapped) == 0)
                io.writeByte(0);
            else if ((w.attr & realized) != 0)
                io.writeByte(2);
            else
                io.writeByte(1);

            io.writeByte((w.attr & overrideRedirect) >> overrideRedirectOffset);
            io.writeInt(w.getColormapId());
            io.writeInt(w.eventMask | w.getOtherEventMask());
            io.writeInt(w.getEventMask(c));
            io.writeShort(w.getDontPropagateMask());
            io.writePad(2);
            io.flush();
        }
    }

    static final void reqCopyPlane(Client c) throws IOException {
        int foo;
        Drawable dsrc = null, ddst = null;
        IO io = c.client;
        foo = io.readInt();
        dsrc = c.lookupDrawable(foo);
        if (dsrc == null) {
            c.errorValue = foo;
            c.errorReason = 9; // Drawable
        }

        int dest = io.readInt();
        ddst = c.lookupDrawable(dest);
        if (ddst == null && c.errorReason == 0) {
            c.errorValue = dest;
            c.errorReason = 9; // Drawable
        }
        foo = io.readInt();
        GC gc = c.lookupGC(foo);
        if (gc == null && c.errorReason == 0) {
            c.errorValue = foo;
            c.errorReason = 13; // BadGC;
        }
        int sx, sy, dx, dy, width, height;

        sx = (short) io.readShort();
        sy = (short) io.readShort();

        int destx, desty;

        destx = (short) io.readShort();
        dx = destx - sx;

        desty = (short) io.readShort();
        dy = desty - sy;

        width = io.readShort();
        height = io.readShort();

        int bplane = io.readInt();
        c.length -= 8;

        if (c.errorReason != 0) {
            return;
        }

        Graphics g = ddst.getGraphics();
        if (((dsrc instanceof Window) && !((Window) dsrc).ddxwindow.isVisible())) {
            g = null;
        }

        if (dsrc.width <= sx || dsrc.height <= sy || (sx + width) <= 0
                || (sy + height) <= 0 || (destx + width) <= 0
                || (desty + height) <= 0) {
            g = null;
        }

        if (g != null) {
            if (dsrc instanceof Window) {
                if (ddst instanceof Window) {
                    ((Window) dsrc).ddxwindow.copyArea(((Window) ddst), gc, sx,
                            sy, width, height, destx, desty);
                }
            } else {
                Image img = null;
                if (ddst instanceof Pixmap) {
                    ((Pixmap) dsrc).copyPlane((Pixmap) ddst, gc, sx, sy, destx,
                            desty, width, height);
                } else {
                    img = ((Pixmap) dsrc).getImage((Window) ddst, gc, sx, sy,
                            width, height);
                    Window wdst = (Window) ddst;

                    if (sx == 0 && sy == 0 && width == dsrc.width
                            && height == dsrc.height) {
                        wdst.ddxwindow.drawImage(gc.clip_mask, img, destx,
                                desty, width, height);
                    } else {
                        java.awt.Shape tmp = g.getClip();
                        g.clipRect(destx, desty, width, height);
                        wdst.ddxwindow.drawImage(gc.clip_mask, img, destx - sx,
                                desty - sy, dsrc.width, dsrc.height);
                        if (tmp == null) {
                            g.setClip(0, 0, wdst.width, wdst.height);
                        } else {
                            g.setClip(tmp);
                        }
                    }
                    wdst.draw(destx, desty, width, height);
                    if (img != ((Pixmap) dsrc).getImage()) {
                        img.flush();
                    }
                }
            }
        }
    }

    static final void reqCopyArea(Client c) throws IOException {
        int foo;
        Drawable dsrc = null, ddst = null;
        IO io = c.client;

        foo = io.readInt();
        dsrc = c.lookupDrawable(foo);
        if (dsrc == null) {
            c.errorValue = foo;
            c.errorReason = 9; // BadDrawable;
        }

        int dest = io.readInt();
        ddst = c.lookupDrawable(dest);
        if (ddst == null && c.errorReason == 0) {
            c.errorValue = dest;
            c.errorReason = 9; // BadDrawable;
        }

        foo = io.readInt();

        GC gc = c.lookupGC(foo);

        if (gc == null && c.errorReason == 0) {
            c.errorValue = foo;
            c.errorReason = 13; // BadGC;
        }

        int sx, sy;
        sx = (short) io.readShort();
        sy = (short) io.readShort();

        int destx, desty;
        destx = (short) io.readShort();
        desty = (short) io.readShort();

        int width, height;
        width = io.readShort();
        height = io.readShort();

        c.length -= 7;

        if (c.errorReason != 0) {
            return;
        }

        Graphics g = ddst.getGraphics();
        if (((dsrc instanceof Window) && !((Window) dsrc).ddxwindow.isVisible())) {
            g = null;
        }

        if (dsrc.width <= sx || dsrc.height <= sy || (sx + width) <= 0
                || (sy + height) <= 0 || (destx + width) <= 0
                || (desty + height) <= 0) {
            g = null;
        }

        /*
         * System.out.println("copyArea: "+dsrc+" sx="+sx+",sy="+sy+ ",
         * w="+width+", h="+height+" "+ ddst+" destx="+destx+",desty="+desty);
         */

        if (g != null) {
            if (dsrc instanceof Window) {

                if (sx < 0) {
                    sx = 0;
                }
                if (sy < 0) {
                    sy = 0;
                }
                if (destx < 0) {
                    destx = 0;
                }
                if (desty < 0) {
                    desty = 0;
                }

                if (ddst instanceof Window) {
                    ((Window) dsrc).ddxwindow.copyArea(((Window) ddst), gc, sx,
                            sy, width, height, destx, desty);
                }
                // else{
                // ((Window)dsrc).ddxwindow.
                // copyArea((Pixmap)ddst, gc,
                // sx, sy, destx, desty, width, height);
                // }
            } else {

                if (ddst instanceof Pixmap) {
                    if (sx < 0) {
                        sx = 0;
                    }
                    if (sy < 0) {
                        sy = 0;
                    }
                    if (destx < 0) {
                        destx = 0;
                    }
                    if (desty < 0) {
                        desty = 0;
                    }

                    ((Pixmap) dsrc).copyArea((Pixmap) ddst, gc, sx, sy, destx,
                            desty, width, height);
                } else {
                    Image img = ((Pixmap) dsrc).getImage((Window) ddst, gc, sx,
                            sy, width, height);

                    Window wdst = (Window) ddst;

                    if (sx == 0 && sy == 0 && width == dsrc.width
                            && height == dsrc.height) {
                        wdst.ddxwindow.drawImage(gc.clip_mask, img, destx,
                                desty, width, height);
                    } else {
                        java.awt.Shape tmp = g.getClip();
                        if (destx >= 0 && desty >= 0) {
                            g.clipRect(destx, desty, width, height);
                        } else {
                            g.clipRect((destx < 0 ? 0 : destx), (desty < 0 ? 0
                                    : desty), (destx < 0 ? width + destx
                                    : width), (desty < 0 ? height + desty
                                    : height));
                        }
                        wdst.ddxwindow.drawImage(gc.clip_mask, img, destx - sx,
                                desty - sy, dsrc.width, dsrc.height);
                        if (tmp == null) {
                            g.setClip(0, 0, wdst.width, wdst.height);
                        } else {
                            g.setClip(tmp);
                        }
                    }
                    wdst.draw(destx, desty, width, height);
                    if (img != ((Pixmap) dsrc).getImage()) {
                        img.flush();
                    }
                }
            }
        }

        if ((gc.attr & GC.graphicsExposures) != 0) {
            c.cevent.mkNoExposure(dest, 0, 62);
            c.sendEvent(c.cevent, 1, 0, Event.NoEventMask, null);
        }
    }

    static final void reqClearArea(Client c) throws IOException {
        int foo;
        int exposures = c.data;
        IO io = c.client;
        foo = io.readInt();
        c.length -= 2;
        Window w = c.lookupWindow(foo);
        if (w == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
            return;
        }

        int x, y, width, height;

        x = (short) io.readShort();
        y = (short) io.readShort();
        width = io.readShort();
        if (width == 0) {
            width = w.width - x;
        }
        height = io.readShort();
        if (height == 0) {
            height = w.height - y;
        }

        c.length -= 2;

        if (c.errorReason != 0) {
            return;
        }

        if (w.getGraphics() != null) { // isMapped??
            w.makeBackgroundTile(x, y, width, height);
            w.draw(x, y, width + 1, height + 1);
        }

        if (exposures != 0) {
            c.cevent.mkExpose(w.id, x, y, width, height, 0);
            c.sendEvent(c.cevent, 1, Event.filters[Event.Expose],
                    Event.filters[Event.Expose], Window.grab);
        }
    }

    void draw() {
        ddxwindow.draw();
    }

    void draw(int x, int y, int width, int height) {
        ddxwindow.draw(x, y, width, height);
    }

    private Window trackParent() {
        Window w = this;
        while (true) {
            if (w.optional != null)
                break;
            w = w.parent;
        }
        return w;
    }

    private Client getClient() {
        return Client.clients[(((id) & Client.CLIENTMASK) >> Client.CLIENTOFFSET)];
    }

    private int getBackingBitPlanes() {
        if (optional == null)
            return ~0;
        return (int) optional.backingBitPlanes;
    }

    private int getBackingPixel() {
        if (optional == null)
            return 0;
        return (int) optional.backingPixel;
    }

    OtherClients getOtherClients() {
        if (optional == null)
            return null;
        return optional.otherClients;
    }

    static java.awt.Frame owner = new java.awt.Frame();

    java.awt.Window frame = null;

    static private final int poolsize = 5;

    static java.awt.Window[] frames = new java.awt.Window[poolsize];

    java.awt.Window getFrame() {
        if (hasFrame())
            return optional.frame;
        if (parent != screen.root) {
            return null;
        }

        makeOptional();
        if (screen.windowmode == WeirdX.RootlessWM
                && !screen.root.redirectSend() && (attr & (1 << 16)) == 0) {
            optional.frame = new java.awt.Frame();
            optional.frame
                    .addMouseListener((java.awt.event.MouseListener) ddxwindow);
            return optional.frame;
        }

        synchronized (Window.class) {
            java.awt.Window foo = null;
            for (int i = 0; i < poolsize; i++) {
                if (frames[i] != null) {
                    foo = frames[i];
                    frames[i] = null;
                    optional.frame = foo;
                    return foo;
                }
            }
        }
        optional.frame = new java.awt.Window(owner);
        return optional.frame;
    }

    boolean hasFrame() {
        return (optional != null && optional.frame != null);
    }

    void delFrame() {
        if (optional == null || optional.frame == null)
            return;
        optional.frame.setVisible(false);
        if (screen.windowmode == WeirdX.RootlessWM
                && optional.frame instanceof java.awt.Frame) {
            optional.frame
                    .removeMouseListener((java.awt.event.MouseListener) ddxwindow);
            // optional.frame.dispose();
            optional.frame = null;
            return;
        }

        synchronized (Window.class) {
            for (int i = 0; i < poolsize; i++) {
                if (frames[i] == null) {
                    frames[i] = optional.frame;
                    optional.frame = null;
                    return;
                }
            }
        }
        optional.frame.dispose();
        optional.frame = null;
    }

    void setProperty(Property p) {
        makeOptional();
        optional.userProps = p;
    }

    Property getProperty() {
        if (optional == null)
            return null;
        return optional.userProps;
    }

    static final void reqConfigureWindow(Client c) throws IOException {
        int foo;
        int n;
        IO io = c.client;
        foo = io.readInt();
        Window win = c.lookupWindow(foo);
        if (win == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow
        }

        int mask = io.readShort();
        io.readPad(2);
        c.length -= 3;
        if (c.errorReason != 0) {
            return;
        }
        if (((win.clss == InputOnly) && (mask & IllegalInputOnlyConfigureMask) != 0)
                || ((mask & CWSibling) != 0 && (mask & CWStackMode) == 0)) {
            c.errorReason = 8; // BadMatch
            return;
        }

        int index;
        int x, y;
        int w = win.width;
        int h = win.height;
        int bw = win.borderWidth;
        Window sib = null;

        synchronized (LOCK) {
            win = c.lookupWindow(win.id);
            if (win == null) {
                c.errorValue = win.id;
                c.errorReason = 3; // BadWindow
                return;
            }
            if (win.screen.root != win && win.parent == null)
                return;
            if (win.parent != null) {
                x = win.x - win.parent.x - bw;
                y = win.y - win.parent.y - bw;
            } else {
                x = win.x;
                y = win.y;
            }

            mask &= 0x7f;

            int beforex = x, beforey = y;

            int smode = 0;
            int tmp = mask;
            while (tmp != 0 && c.length != 0) {
                index = lowbit(tmp);
                tmp &= ~index;
                switch (index) {
                case CWX:
                    foo = io.readInt();
                    foo = (short) (foo & 0xffff);
                    if (foo == x) {
                        mask -= CWX;
                    } else {
                        x = (short) (foo);
                    }
                    break;
                case CWY:
                    foo = io.readInt();
                    foo = (short) (foo & 0xffff);
                    if (foo == y) {
                        mask -= CWY;
                    } else {
                        y = (short) (foo);
                    }
                    break;
                case CWWidth:
                    foo = io.readInt();
                    foo = (foo & 0xffff);
                    if (w == foo) {
                        mask -= CWWidth;
                    } else {
                        w = foo;
                    }
                    break;
                case CWHeight:
                    foo = io.readInt();
                    foo = (foo & 0xffff);
                    if (h == foo) {
                        mask -= CWHeight;
                    } else {
                        h = foo;
                    }
                    break;
                case CWBorderWidth:
                    foo = io.readInt();
                    foo = (foo & 0xffff);
                    bw = foo;
                    break;
                case CWSibling:
                    foo = io.readInt();
                    sib = c.lookupWindow(foo);
                    if (sib == null) {
                        c.errorValue = foo;
                        c.errorReason = 3; // BadWindow
                    } else if ((sib.parent != win.parent) || (sib == win)) {
                        c.errorReason = 8; // BadMatch
                    }
                    break;
                case CWStackMode:
                    foo = io.readInt();
                    foo &= 0xff;
                    smode = foo;
                    if ((smode != TopIf) && (smode != BottomIf)
                            && (smode != Opposite) && (smode != Above)
                            && (smode != Below)) {
                        c.errorValue = foo;
                        c.errorReason = 2; // BadValue
                    }
                    break;
                default:
                    c.errorValue = mask;
                    c.errorReason = 2; // BadValue
                    return;
                }
                c.length--;
                if (c.errorReason != 0) {
                    return;
                }
            }
            if (c.length != 0) {
                c.errorValue = mask;
                c.errorReason = 2; // BadValue
                return;
            }

            if (mask == 0) {
                return;
            }

            if (win.parent == null)
                return;

            if ((mask & CWStackMode) != 0) {
                sib = win.getPlaceInTheStack(sib, win.parent.x + x,
                        win.parent.y + y, w + bw * 2, h + bw * 2, smode);
            } else {
                sib = win.nextSib;
            }

            if (((win.attr & overrideRedirect) == 0)
                    && (win.parent.redirectSend())) {
                c.cevent.mkConfigureRequest(((mask & CWStackMode) != 0) ? smode
                        : Above, win.parent.id, win.id,
                        ((mask & CWSibling) != 0) ? sib.id : 0, x, y, w, h, bw,
                        mask);
                if (win.parent.sendEvent(c.cevent, 1,
                        Event.SubstructureRedirectMask, c) == 1) {
                    return;
                }

            }

            int action = Restack;
            if ((mask & (CWX | CWY)) != 0 && (mask & (CWHeight | CWWidth)) == 0) {
                action = Move;
            } else if ((mask & ChangeMask) != 0) {
                if (w == 0 || h == 0) {
                    c.errorValue = 0;
                    c.errorReason = 2; // BadBalue;
                    return;
                }
                action = Resize;
            }

            if (action == Resize) {
                boolean sizec = ((w != win.width) || (h != win.height));
                if (sizec
                        && (((win.eventMask | win.getOtherEventMask()) & Event.ResizeRedirectMask) != 0)) {
                    c.cevent.mkResizeRequest(win.id, w, h);
                    if (win.sendEvent(c.cevent, 1, Event.ResizeRedirectMask, c) == 1) {
                        w = win.width;
                        h = win.height;
                        sizec = false;
                    }
                }
                if (!sizec) {
                    if ((mask & (CWX | CWY)) != 0)
                        action = Move;
                    else if ((mask & (CWStackMode | CWBorderWidth)) != 0) {
                        action = Restack;
                    } else {
                        return;
                    }
                }
            }

            if ((action == Resize) || (((mask & CWX) != 0) && x != beforex)
                    || (((mask & CWY) != 0) && y != beforey)
                    || (((mask & CWBorderWidth) != 0) && bw != win.borderWidth)
                    || (((mask & CWStackMode) != 0) && win.nextSib != sib)) {
                if (win.substrSend()) {
                    c.cevent.mkConfigureNotify(win.id, (sib != null ? sib.id
                            : 0), x, y, w, h, bw,
                            (win.attr & overrideRedirect) != 0 ? 0 : 1);
                    win.sendEvent(c.cevent, 1, null);
                }

                if ((mask & CWBorderWidth) != 0) {
                    if (action == Restack) {
                        action = Move;
                        win.borderWidth = bw;
                        win.ddxwindow.setBorder(bw);
                    } else if ((action == Move)
                            && ((beforex + win.borderWidth) == x + bw)
                            && ((beforey + win.borderWidth) == y + bw)) {
                        action = Reborder;
                    } else {
                        win.borderWidth = bw;
                        win.ddxwindow.setBorder(bw);
                    }
                }

                if ((mask & CWStackMode) != 0) {
                    win.reflectStackChange(sib);
                }

                if (((mask & CWX) != 0) || ((mask & CWY) != 0)
                        || ((mask & CWWidth) != 0) || ((mask & CWHeight) != 0)
                        || ((mask & CWBorderWidth) != 0)) {
                    win.origin.x = x + bw;
                    win.origin.y = y + bw;

                    int dx, dy, dw, dh;
                    dx = dy = dw = dh = 0;
                    dw = w - win.width;
                    dh = h - win.height;
                    win.height = h;
                    win.width = w;

                    int newx = win.parent.x + x + bw;
                    int newy = win.parent.y + y + bw;

                    int oldx, oldy;
                    oldx = win.x;
                    oldy = win.y;

                    x = win.x = newx;
                    y = win.y = newy;

                    Window wToValidate = win.moveInStack(sib);
                    if (((mask & CWWidth) != 0) || ((mask & CWHeight) != 0)
                            || ((mask & CWBorderWidth) != 0)) {
                        if (win.screen.windowmode != WeirdX.InBrowser
                                && win.hasFrame()) {
                            java.awt.Window frame = win.getFrame();
                            frame.validate();
                            Insets insets = frame.getInsets();
                            frame.setSize(win.width + win.borderWidth * 2
                                    + insets.left + insets.right, win.height
                                    + win.borderWidth * 2 + insets.bottom
                                    + insets.top);
                            frame.validate();
                        }

                        win.ddxwindow.setSize(win.width, win.height);
                    }

                    win.resizeChildrenWinSize(x - oldx, y - oldy, dw, dh);
                    win.ddxwindow.setLocation(win.origin.x - win.borderWidth
                            + win.parent.borderWidth, win.origin.y
                            - win.borderWidth + win.parent.borderWidth);

                }
                return;
            } else {
                return;
            }
        }
    }

    private int getDontPropagateMask() {
        if (optional == null)
            return DontPropagate.masks[(attr & dontPropagate) >> dontPropagateOffset];
        return optional.dontPropagateMask;
    }

    Grab getPassiveGrabs() {
        if (optional == null)
            return null;
        return optional.passiveGrabs;
    }

    int getOtherEventMask() {
        if (optional == null)
            return 0;
        return optional.otherEventMasks;
    }

    void setColormap(Colormap cmap) {
        makeOptional();
        optional.colormap = cmap;
    }

    Colormap getColormap() {
        return trackParent().optional.colormap;
    }

    private int getColormapId() {
        if (clss == InputOnly)
            return 0;
        return getColormap().id;
    }

    void setVisual(int id) {
        makeOptional();
        optional.visual = id;
    }

    private int getVisual() {
        return trackParent().optional.visual;
    }

    boolean isMapped() {
        return (attr & mapped) != 0;
    }

    boolean isRealized() {
        return (attr & realized) != 0;
    }

    boolean isViewable() {
        return (attr & viewable) != 0;
    }

    boolean isBorderPixel() {
        return (attr & borderIsPixel) != 0;
    }

    void setBorderIsPixel() {
        attr |= borderIsPixel;
    }

    void setBackgroundIsPixel() {
        attr &= ~backgroundState;
        attr |= BackgroundPixel;
    }

    boolean hasParentRelativeBorder() {
        return (attr & borderIsPixel) == 0 && hasBorder()
                && (attr & backgroundState) == ParentRelative;
    }

    boolean hasBorder() {
        return borderWidth != 0;
    }

    private void reflectStackChange(Window sib) throws IOException {
        boolean wasViewable = (attr & viewable) != 0;
        if (parent == null)
            return;

        Window firstChange = moveInStack(sib);
        if ((attr & realized) != 0) {
            restructured();
        }
    }

    private int isSiblingAboveMe(Window sib) {
        Window win = parent.firstChild;
        while (win != null) {
            if (win == sib)
                return (Above);
            else if (win == this)
                return (Below);
            win = win.nextSib;
        }
        return (Below);
    }

    private Window getPlaceInTheStack(Window sib, int x, int y, int w, int h,
            int smode) {
        if ((this == parent.firstChild) && (this == parent.lastChild))
            return null;

        Window first = parent.firstChild;
        switch (smode) {
        case Above:
            if (sib != null)
                return (sib);
            else if (this == first)
                return (nextSib);
            else
                return (first);
        case Below:
            if (sib != null)
                if (sib.nextSib != this)
                    return (sib.nextSib);
                else
                    return (nextSib);
            else
                return null;
        case TopIf:
            if ((((attr & mapped) == 0) || (sib != null && (sib.attr & mapped) == 0)))
                return (nextSib);
            else if (sib != null) {
                if ((isSiblingAboveMe(sib) == Above))
                    return (first);
                else
                    return (nextSib);
            } else
                return (first);
        case BottomIf:
            if ((((attr & mapped) == 0) || (sib != null && (sib.attr & mapped) == 0)))
                return (nextSib);
            else if (sib != null) {
                if ((isSiblingAboveMe(sib) == Below))
                    return null;
                else
                    return (nextSib);
            } else
                return null;
        case Opposite:
            if ((((attr & mapped) == 0) || (sib != null && (sib.attr & mapped) == 0)))
                return (nextSib);
            else if (sib != null) {
                if (isSiblingAboveMe(sib) == Above)
                    return (first);
                else
                    return null;
            } else
                return (first);
        default:
            return nextSib;
        }
    }

    private Window moveInStack(Window next) {
        Window firstChange = this;
        synchronized (LOCK) {
            if (nextSib != next) {
                if (next == null) { // to bottom
                    if (parent.firstChild == this)
                        parent.firstChild = nextSib;
                    firstChange = nextSib;
                    nextSib.prevSib = prevSib;
                    if (prevSib != null)
                        prevSib.nextSib = nextSib;
                    parent.lastChild.nextSib = this;
                    prevSib = parent.lastChild;
                    nextSib = null;
                    parent.lastChild = this;

                    if (screen.windowmode == WeirdX.InBrowser
                            || parent != screen.root) {
                        parent.ddxwindow.add(
                                (java.awt.Component) (this.ddxwindow), -1);
                    }
                } else if (parent.firstChild == next) { // to top
                    firstChange = this;
                    if (parent.lastChild == this)
                        parent.lastChild = prevSib;
                    if (nextSib != null)
                        nextSib.prevSib = prevSib;
                    if (prevSib != null)
                        prevSib.nextSib = nextSib;
                    nextSib = parent.firstChild;
                    prevSib = null;
                    next.prevSib = this;
                    parent.firstChild = this;

                    if (screen.windowmode == WeirdX.InBrowser
                            || parent != screen.root) {
                        parent.ddxwindow.add(
                                (java.awt.Component) (this.ddxwindow), 0);
                    }
                } else { // in middle
                    Window pOldNext = nextSib;
                    firstChange = null;
                    if (parent.firstChild == this)
                        firstChange = parent.firstChild = nextSib;
                    if (parent.lastChild == this) {
                        firstChange = this;
                        parent.lastChild = prevSib;
                    }
                    if (nextSib != null)
                        nextSib.prevSib = prevSib;
                    if (prevSib != null)
                        prevSib.nextSib = nextSib;
                    nextSib = next;
                    prevSib = next.prevSib;
                    if (next.prevSib != null)
                        next.prevSib.nextSib = this;
                    next.prevSib = this;
                    if (firstChange == null) {
                        firstChange = parent.firstChild;
                        while ((firstChange != this)
                                && (firstChange != pOldNext))
                            firstChange = firstChange.nextSib;
                    }

                    Component[] component = parent.ddxwindow.getComponents();
                    for (int i = 0; i < component.length; i++) {
                        if (component[i] == next.ddxwindow) {
                            if (i != 0)
                                i--;
                            if (screen.windowmode == WeirdX.InBrowser
                                    || parent != screen.root) {
                                parent.ddxwindow.add(
                                        (java.awt.Component) (this.ddxwindow),
                                        i);
                            }
                            break;
                        }
                    }
                }
            }
        }
        this.draw();
        return firstChange;
    }

    static final void reqReparentWindow(Client c) throws IOException {
        int foo;
        int x, y;
        IO io = c.client;

        foo = io.readInt();
        Window win = c.lookupWindow(foo);
        if (win == null) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
        }

        foo = io.readInt();
        Window parent = c.lookupWindow(foo);
        if (parent == null && c.errorReason == 0) {
            c.errorValue = foo;
            c.errorReason = 3; // BadWindow;
        }

        x = (short) io.readShort();
        y = (short) io.readShort();

        c.length -= 4;

        if (c.errorReason != 0)
            return;
        win.reparent(parent, x, y, c);
    }

    void reparent(Window newparent, int xx, int yy, Client c)
            throws IOException {
        boolean wasMapped;

        synchronized (LOCK) {
            if (parent == null)
                return;

            int bw = borderWidth;
            wasMapped = ((attr & mapped) != 0);
            Window prev;

            makeOptional();

            if (wasMapped) {
                unmapWindow(false);
            }

            c.cevent.mkReparentNotify(id, id, newparent.id, xx, yy,
                    ((attr & overrideRedirect) != 0 ? 1 : 0));

            sendEvent(c.cevent, 1, newparent);

            prev = parent;
            if (prev.firstChild == this)
                prev.firstChild = nextSib;
            if (prev.lastChild == this)
                prev.lastChild = prevSib;

            if (nextSib != null)
                nextSib.prevSib = prevSib;
            if (prevSib != null)
                prevSib.nextSib = nextSib;

            parent = newparent;

            nextSib = newparent.firstChild;
            prevSib = null;
            if (newparent.firstChild != null)
                newparent.firstChild.prevSib = this;
            else
                newparent.lastChild = this;
            newparent.firstChild = this;

            origin.x = (short) (xx);
            origin.y = (short) (yy);
            x = (short) (xx + newparent.x);
            y = (short) (yy + newparent.y);

            if (screen.windowmode != WeirdX.InBrowser && hasFrame()) {
                java.awt.Window frame = getFrame();
                frame.remove((java.awt.Component) ddxwindow);
                // frame.dispose();
                delFrame();
            }
            if (screen.windowmode != WeirdX.InBrowser
                    && newparent == screen.root) {
                java.awt.Window frame = getFrame();
                /*
                 * if(frame instanceof JFrame){
                 * ((JFrame)frame).setJMenuBar(null);
                 * ((JFrame)frame).getContentPane().setLayout(null);
                 * ((JFrame)frame).setResizable(false); } else
                 */if (frame instanceof Frame) {
                    ((Frame) frame).setMenuBar(null);
                    ((Frame) frame).setResizable(true);
                }

                ddxwindow.setLocation(0, 0);

                frame.add((java.awt.Component) ddxwindow);

                frame.validate();
                Insets insets = frame.getInsets();
                frame.setSize(this.width + this.borderWidth * 2 + insets.left
                        + insets.right, this.height + this.borderWidth * 2
                        + insets.bottom + insets.top);
                frame.validate();

                if (frame instanceof Frame) {
                    addWindowListener((java.awt.Frame) frame);
                    addComponentListener((java.awt.Frame) frame);
                }
            } else {
                newparent.ddxwindow.add((java.awt.Component) ddxwindow, 0); // ???
                ddxwindow.setLocation(origin.x - borderWidth
                        + parent.borderWidth, origin.y - borderWidth
                        + parent.borderWidth);
            }

            resizeChildrenWinSize(0, 0, 0, 0);

            if (wasMapped) {
                mapWindow(c);
            }

            recalculateDeliverableEvents();
        }
    }

    void recalculateDeliverableEvents() {
        OtherClients others;

        Window child = this;
        while (true) {
            if (child.optional != null) {
                child.optional.otherEventMasks = 0;
                others = (optional == null) ? null : optional.otherClients;
                for (; others != null; others = (OtherClients) others.next) {
                    child.optional.otherEventMasks |= others.mask;
                }
            }

            child.deliverableEvents = child.eventMask
                    | child.getOtherEventMask();
            if (child.parent != null)
                child.deliverableEvents |= (child.parent.deliverableEvents
                        & Event.PropagateMask & ~(child.getDontPropagateMask()));

            if (child.firstChild != null) {
                child = child.firstChild;
                continue;
            }

            while (child.nextSib == null && (child != this))
                child = child.parent;
            if (child == this)
                break;
            child = child.nextSib;
        }
    }

    final Graphics getGraphics() {
        if (clss == InputOnly)
            return ddxwindow.getGraphics();
        else
            return ddxwindow.getGraphics2();
    }

    final Graphics getGraphics(GC gc, int mask) {
        if (clss == InputOnly)
            return ddxwindow.getGraphics();
        else
            return ddxwindow.getGraphics(gc, mask);
    }

    final Image getImage() {
        return ddxwindow.getImage();
    }

    final Image getImage(int x, int y, int width, int height) {
        return ddxwindow.getImage(null, x, y, width, height);
    }

    final Image getImage(GC gc, int x, int y, int width, int height) {
        return ddxwindow.getImage(gc, x, y, width, height);
    }

    private void setEventMask(Client c, int mask) {
        int check;
        OtherClients others;
        check = (mask & Event.AtMostOneClient);
        if ((check & (eventMask | getOtherEventMask())) != 0) {
            if (getClient() != c && (check & eventMask) != 0) {
                c.errorReason = 10; // BadAccess
            }
            for (others = getOtherClients(); others != null; others = (OtherClients) others.next) {
                if (!others.sameClient(c) && (check & others.mask) != 0) {
                    c.errorReason = 10; // BadAccess
                    return;
                }
            }
        }
        if (client == c) {
            check = eventMask;
            eventMask = mask;
        } else {
            others = (optional == null) ? null : optional.otherClients;
            for (; others != null; others = (OtherClients) others.next) {
                if (others.sameClient(c)) {
                    check = others.mask;
                    if (mask == 0) {
                        Resource.freeResource(others.id, RT_NONE);
                        return;
                    } else {
                        others.mask = mask;
                    }
                    recalculateDeliverableEvents();
                    return;
                }
            }
            check = 0;
            makeOptional();

            others = new OtherClients(Resource.fakeClientId(c));
            others.mask = mask;
            others.resource = others.id;
            others.window = this;
            others.next = optional.otherClients;
            optional.otherClients = others;
            Resource.add(others);
        }
        recalculateDeliverableEvents();
        return;
    }

    private static void gravityTranslate(int newx, int newy, int oldx,
            int oldy, int dw, int dh, int gravity, Point point) {
        switch (gravity) {
        case NorthGravity:
            point.x = newx + dw / 2;
            point.y = newy;
            break;
        case NorthEastGravity:
            point.x = newx + dw;
            point.y = newy;
            break;
        case WestGravity:
            point.x = newx;
            point.y = newy + dh / 2;
            break;
        case CenterGravity:
            point.x = newx + dw / 2;
            point.y = newy + dh / 2;
            break;
        case EastGravity:
            point.x = newx + dw;
            point.y = newy + dh / 2;
            break;
        case SouthWestGravity:
            point.x = newx;
            point.y = newy + dh;
            break;
        case SouthGravity:
            point.x = newx + dw / 2;
            point.y = newy + dh;
            break;
        case SouthEastGravity:
            point.x = newx + dw;
            point.y = newy + dh;
            break;
        case StaticGravity:
            point.x = oldx;
            point.y = oldy;
            break;
        default:
            point.x = newx;
            point.y = newy;
            break;
        }
    }

    private void resizeChildrenWinSize(int dx, int dy, int dw, int dh)
            throws IOException {
        boolean resized = (dw != 0 || dh != 0);
        for (Window sib = firstChild; sib != null; sib = sib.nextSib) {
            if (resized
                    && (((sib.attr & winGravity) >> winGravityOffset) > NorthWestGravity)) {
                int newx = sib.origin.x;
                int newy = sib.origin.y;
                gravityTranslate(newx, newy, newx - dx, newy - dy, dw, dh,
                        (sib.attr & winGravity) >> winGravityOffset, gpoint);
                if (gpoint.x != sib.origin.x || gpoint.y != sib.origin.y) {
                    Event event = new Event();
                    event.mkGravityNotify(sib.id, sib.id, gpoint.x
                            - sib.borderWidth, gpoint.y - sib.borderWidth);
                    sib.sendEvent(event, 1, null);
                    sib.origin.x = gpoint.x;
                    sib.origin.y = gpoint.y;
                }
            }

            sib.x = x + sib.origin.x;
            sib.y = y + sib.origin.y;
            if (sib.ddxwindow != null) // ??
                sib.ddxwindow.setLocation(sib.origin.x - sib.borderWidth
                        + sib.parent.borderWidth, sib.origin.y
                        - sib.borderWidth + sib.parent.borderWidth);
            Window child = sib.firstChild;
            if (child != null) {
                while (true) {
                    child.x = child.parent.x + child.origin.x;
                    child.y = child.parent.y + child.origin.y;
                    if (child.ddxwindow != null) // ??
                        child.ddxwindow.setLocation(child.origin.x
                                - child.borderWidth + child.parent.borderWidth,
                                child.origin.y - child.borderWidth
                                        + child.parent.borderWidth);
                    if (child.firstChild != null) {
                        child = child.firstChild;
                        continue;
                    }
                    while (child.nextSib == null && (child != sib))
                        child = child.parent;
                    if (child == sib)
                        break;
                    child = child.nextSib;
                }
            }
        }
    }

    static boolean checkDeviceGrabs(Event e, int checkFirst, int count)
            throws IOException {

        Window win;
        int i = checkFirst;
        for (; i < spriteTraceGood; i++) {
            win = spriteTrace[i];
            if (win.optional != null && win.checkPassiveGrabsOnWindow(e, count)) {
                return true;
            }
        }
        return false;
    }

    boolean checkPassiveGrabsOnWindow(Event e, int count) throws IOException {
        Grab grab = getPassiveGrabs();

        if (grab == null)
            return false;

        synchronized (LOCK) {
            Grab tempGrab = new Grab(Resource.fakeClientId(client));
            tempGrab.window = this;
            tempGrab.type = e.getType();
            tempGrab.detail.exact = e.getDetail();
            tempGrab.detail.pMask = null;
            tempGrab.modifiersDetail.pMask = null;
            tempGrab.modifiersDetail.exact = e.getState() & 0x0f;
            for (; grab != null; grab = grab.next) {
                if (tempGrab.grabMatchesSecond(grab)
                        && (grab.confineTo == null || ((grab.confineTo.attr & realized) != 0 && (grab.confineTo.x != 0 || grab.confineTo.y != 0)))) {
                    grab.activatePointerGrab((int) System.currentTimeMillis(),
                            true);
                    e.fixUpEventFromWindow(grab.window, 0, Window.sprite.hot.x,
                            Window.sprite.hot.y, true);
                    if (grab.getClient() != null)
                        grab.getClient().sendEvent(e, count,
                                Event.filters[e.getType()],
                                Event.filters[e.getType()], grab);
                    return true;
                }
            }
        }
        return false;
    }

    static void sendGrabbedEvent(Event e, boolean deactivateGrab, int count)
            throws IOException {
        Grab grab = Window.grab;
        int deliveries = 0;

        if ((grab.attr & Grab.ownerEvents) != 0) {
            Window focus = null;
            if (focus == null)
                deliveries = sendDeviceEvent(sprite.win, e, grab, null, count);
            else if (focus != null
                    && (focus == sprite.win || focus.isParent(sprite.win)))
                deliveries = sendDeviceEvent(sprite.win, e, grab, focus, count);
            else if (focus != null)
                deliveries = sendDeviceEvent(focus, e, grab, focus, count);
        }

        if (deliveries == 0) {
            e.fixUpEventFromWindow(grab.window, 0, sprite.hot.x, sprite.hot.y,
                    true);
            if (grab.getClient() != null)
                deliveries = grab.getClient().sendEvent(e, count,
                        grab.eventMask, Event.filters[e.getType()], grab);
        }
    }

    static int sendDeviceEvent(Window win, Event e, Grab grab, Window stopAt,
            int count) throws IOException {
        int child = 0;
        int type = e.getType();
        int filter = Event.filters[type];
        int deliveries = 0;

        if ((type & Event.EXTENSION_EVENT_BASE) != 0) {
            OtherInputMasks inputMasks;
            int mskidx = 0;
            inputMasks = (win.optional == null ? null
                    : win.optional.otherInputMasks);
            if (inputMasks != null
                    && (filter & inputMasks.deliverableEvents[mskidx]) == 0)
                return 0;
            while (win != null) {
                if (inputMasks != null
                        && (inputMasks.inputEvents[mskidx] & filter) != 0) {
                    e.fixUpEventFromWindow(win, child, sprite.hot.x,
                            sprite.hot.y, false);
                    deliveries = win.sendEvent(e, count, filter, grab, mskidx);
                    if (deliveries > 0)
                        return deliveries;
                }
                if ((deliveries < 0)
                        || (win == stopAt)
                        || (inputMasks != null && (filter & inputMasks.dontPropagateMask[mskidx]) != 0))
                    return 0;
                child = win.id;
                win = win.parent;
                if (win != null) {
                    inputMasks = (win.optional == null ? null
                            : win.optional.otherInputMasks);
                }
            }
        } else {
            if ((filter & win.deliverableEvents) == 0)
                return 0;

            while (win != null) {
                if (((win.getOtherEventMask() | win.eventMask) & filter) != 0) {
                    e.fixUpEventFromWindow(win, child, sprite.hot.x,
                            sprite.hot.y, false);
                    deliveries = win.sendEvent(e, count, filter, grab, 0);
                    if (deliveries > 0)
                        return deliveries;
                }
                if ((deliveries < 0) || (win == stopAt)
                        || ((filter & win.getDontPropagateMask()) != 0))
                    return 0;
                child = win.id;
                win = win.parent;
            }
        }
        return 0;
    }

    boolean isParent(Window w) {
        for (w = w.parent; w != null; w = w.parent) {
            if (w == this)
                return true;
        }
        return false;
    }

    Window commonAncestor(Window w) {
        for (w = w.parent; w != null; w = w.parent) {
            if (w.isParent(this))
                return w;
        }
        return null;
    }

    private static void doFocusEvents(Client c, int fromWin, int toWin, int mode)
            throws IOException {
        int out, in;

        if (fromWin == toWin)
            return;

        out = (fromWin == 0) ? NotifyDetailNone : NotifyPointerRoot;
        in = (toWin == 0) ? NotifyDetailNone : NotifyPointerRoot;

        if ((toWin == 0) || (toWin == 1)) {
            if ((fromWin == 0) || (fromWin == 1)) {
                if (fromWin == 1) {
                    focusOutEvents(c, sprite.win, sprite.win.screen.root, mode,
                            NotifyPointer, true);
                }
            } else {
                Window from = (c != null) ? c.lookupWindow(fromWin)
                        : (Window) Resource.lookupIDByClass(fromWin,
                                Resource.RC_DRAWABLE);
                if (from == null)
                    return;
                if (from.isParent(sprite.win)) {
                    focusOutEvents(c, sprite.win, from, mode, NotifyPointer,
                            false);
                }
                from.sendFocusEvent(c, Event.FocusOut, mode, NotifyNonlinear);
                focusOutEvents(c, from.parent, null, mode,
                        NotifyNonlinearVirtual, false);
            }

            if (toWin == 1) {
                focusInEvents(c, sprite.win.screen.root, sprite.win, null,
                        mode, NotifyPointer, true);
            }
        } else {
            if ((fromWin == 0) || (fromWin == 1)) {
                if (fromWin == 1) {
                    focusOutEvents(c, sprite.win, sprite.win.screen.root, mode,
                            NotifyPointer, true);
                }

                Window to = (c != null) ? c.lookupWindow(toWin)
                        : (Window) Resource.lookupIDByClass(toWin,
                                Resource.RC_DRAWABLE);
                if (to == null)
                    return;
                if (to.parent != null) {
                    focusInEvents(c, to.screen.root, to, to, mode,
                            NotifyNonlinearVirtual, true);
                }
                to.sendFocusEvent(c, Event.FocusIn, mode, NotifyNonlinear);
                if (to.isParent(sprite.win)) {
                    focusInEvents(c, to, sprite.win, null, mode, NotifyPointer,
                            false);
                }
            } else {
                Window to = (c != null) ? c.lookupWindow(toWin)
                        : (Window) Resource.lookupIDByClass(toWin,
                                Resource.RC_DRAWABLE);
                Window from = (c != null) ? c.lookupWindow(fromWin)
                        : (Window) Resource.lookupIDByClass(fromWin,
                                Resource.RC_DRAWABLE);
                if (from == null || to == null)
                    return;
                if (to.isParent(from)) {
                    from
                            .sendFocusEvent(c, Event.FocusOut, mode,
                                    NotifyAncestor);
                    focusOutEvents(c, from.parent, to, mode, NotifyVirtual,
                            false);
                    to.sendFocusEvent(c, Event.FocusIn, mode, NotifyInferior);
                    if ((to.isParent(sprite.win)) && (sprite.win != from)
                            && (!from.isParent(sprite.win))
                            && (!sprite.win.isParent(from))) {
                        focusInEvents(c, to, sprite.win, null, mode,
                                NotifyPointer, false);
                    }
                } else {
                    if (from.isParent(to)) {
                        if ((from.isParent(sprite.win)) && (sprite.win != from)
                                && (!to.isParent(sprite.win))
                                && (!sprite.win.isParent(to))) {
                            focusOutEvents(c, sprite.win, from, mode,
                                    NotifyPointer, false);
                        }
                        from.sendFocusEvent(c, Event.FocusOut, mode,
                                NotifyInferior);
                        focusInEvents(c, from, to, to, mode, NotifyVirtual,
                                false);
                        to.sendFocusEvent(c, Event.FocusIn, mode,
                                NotifyAncestor);
                    } else {
                        Window common = to.commonAncestor(from);

                        if (from.isParent(sprite.win)) {
                            focusOutEvents(c, sprite.win, from, mode,
                                    NotifyPointer, false);
                        }
                        from.sendFocusEvent(c, Event.FocusOut, mode,
                                NotifyNonlinear);
                        if (from.parent != null) {
                            focusOutEvents(c, from.parent, common, mode,
                                    NotifyNonlinearVirtual, false);
                        }
                        if (to.parent != null) {
                            focusInEvents(c, common, to, to, mode,
                                    NotifyNonlinearVirtual, false);
                        }
                        to.sendFocusEvent(c, Event.FocusIn, mode,
                                NotifyNonlinear);
                        if (to.isParent(sprite.win)) {
                            focusInEvents(c, to, sprite.win, null, mode,
                                    NotifyPointer, false);
                        }
                    }
                }
            }
        }
    }

    private static void focusOutEvents(Client c, Window child, Window ancestor,
            int mode, int detail, boolean doAncestor) throws IOException {
        for (Window win = child; win != ancestor; win = win.parent) {
            win.sendFocusEvent(c, Event.FocusOut, mode, detail);
        }
        if (doAncestor) {
            ancestor.sendFocusEvent(c, Event.FocusOut, mode, detail);
        }
    }

    private static boolean focusInEvents(Client c, Window ancestor,
            Window child, Window skipChild, int mode, int detail,
            boolean doAncestor) throws IOException {
        if (child == null) {
            return ancestor == null;
        }
        if (ancestor == child) {
            if (doAncestor) {
                child.sendFocusEvent(c, Event.FocusIn, mode, detail);
            }
            return true;
        }
        if (focusInEvents(c, ancestor, child.parent, skipChild, mode, detail,
                doAncestor)) {
            if (child != skipChild) {
                child.sendFocusEvent(c, Event.FocusIn, mode, detail);
            }
            return true;
        }
        return false;
    }

    void sendFocusEvent(Client c, int type, int mode, int detail)
            throws IOException {
        Event event = (c != null) ? c.cevent : new Event();
        if (type == Event.FocusIn) {
            event.mkFocusIn(detail, id, mode);
        } else if (type == Event.FocusOut) {
            event.mkFocusOut(detail, id, mode);
        } else {
            return;
        }
        sendEvent(event, 1, Event.filters[type], null, 0);
    }

    void initAttr() {
        setBackgroundIsPixel();
        background.pixel = screen.white;
        setBorderIsPixel();
        border.pixel = screen.black;
        borderWidth = 0;
    }

    void restoreClip() {
        ddxwindow.restoreClip();
    }

    private static int lowbit(int mask) {
        int result = 1;
        for (int i = 0; i < 32; i++) {
            if ((mask & 1) == 1) {
                result = result << i;
                break;
            }
            mask = mask >> 1;
        }
        return result;
    }

    static void printWindow(Window p1, int indent) {
        for (int i = 0; i < indent; i++)
            System.err.print(" ");
        try {
            System.err.print(Integer.toHexString(p1.id));
            // System.err.print(" mapped: "+p1.isMapped());
            // System.err.print(", realized: "+p1.isRealized());
            System.err.print(" (" + p1.x + "," + p1.y + "," + p1.width + ","
                    + p1.height + ")");
            // System.err.print(" location: "+p1.ddxwindow.getLocation());
            System.err.println(" isVisible: " + p1.ddxwindow.isVisible());
        } catch (Exception ee) {
        }
    }

    static void printChildren(Window p1, int indent) {
        Window p2;
        while (p1 != null) {
            p2 = p1.firstChild;
            printWindow(p1, indent);
            printChildren(p2, indent + 4);
            p1 = p1.nextSib;
        }
    }

    static void printWindowTree(Window win) {
        System.err.println("printWindowTree");
        printWindow(win, 0);
        Window p1;
        for (int i = 0; i < 1; i++) {
            p1 = win.firstChild;
            printChildren(p1, 4);
        }
    }

    private void addWindowListener(java.awt.Frame foo) {
        final java.awt.Frame frame = foo;
        frame.addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent e) {
            }

            public void windowClosing(java.awt.event.WindowEvent e) {
                int message_type = Atom.find("WM_PROTOCOLS");
                int del = Atom.find("WM_DELETE_WINDOW");

                synchronized (Window.LOCK) {
                    Property p = getProperty();
                    while (p != null) {
                        if (p.propertyName == message_type)
                            break;
                        p = p.next;
                    }

                    if (p != null && p.data != null) {
                    } else {
                        try {
                            getClient().closeDown();
                        } catch (Exception ee) {
                        }
                        return;
                    }
                }

                if (message_type == 0 || del == 0)
                    return;

                Event event = new Event();
                event.mkClientMessage(id, message_type);
                byte[] eb = event.event;
                eb[1] = 32;

                eb[12] = (byte) (del >>> 24); // protocol
                eb[13] = (byte) (del >>> 16);
                eb[14] = (byte) (del >>> 8);
                eb[15] = (byte) (del);

                int tm = (int) System.currentTimeMillis();
                eb[16] = (byte) (tm >>> 24); // time
                eb[17] = (byte) (tm >>> 16);
                eb[18] = (byte) (tm >>> 8);
                eb[19] = (byte) (tm);

                eb[20] = eb[21] = eb[22] = eb[23] = 0;
                eb[24] = eb[25] = eb[26] = eb[27] = 0;
                eb[28] = eb[29] = eb[30] = eb[31] = 0;

                eb[0] |= 0x80;

                try {
                    sendEvent(event, 1, Event.NoEventMask, null, 0);
                } catch (Exception ee) {
                }
            }
        });
    }

    private void addComponentListener(java.awt.Frame foo) {
        final java.awt.Frame frame = foo;
        frame.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent e) {
                if (parent == null)
                    return;
                Rectangle rectangle = frame.getBounds();
                if (rectangle.width == 0 || rectangle.height == 0)
                    return;
                if (frame_width != rectangle.width
                        || frame_height != rectangle.height) {
                    Insets insets = frame.getInsets();
                    synchronized (Window.LOCK) {
                        try {
                            Point point = frame.getLocation();
                            int ww = rectangle.width - insets.left
                                    - insets.right - borderWidth * 2;
                            int hh = rectangle.height - insets.top
                                    - insets.bottom - borderWidth * 2;
                            if (ww > 0 && hh > 0) {
                                ddxwindow.setSize(ww, hh);
                                frame.pack();
                                Event event = new Event();
                                event.mkConfigureNotify(id, id,
                                        (rectangle.x + insets.left),
                                        (rectangle.y + insets.top), ww, hh,
                                        borderWidth,
                                        (attr & (1 << 16)) != 0 ? 1 : 0);
                                sendEvent(event, 1, null);
                                frame_x = rectangle.x;
                                frame_y = rectangle.y;
                                frame_width = rectangle.width;
                                frame_height = rectangle.height;
                            }
                        } catch (Exception ee) {
                            System.out.println(ee);
                        }
                    }
                }
            }
        });
    }

}

class InputClients extends Clients {
    int[] mask;

    InputClients(int id) {
        super(id);
        mask = new int[9/* EMASKSIZE */];
    }
}

class OtherInputMasks {
    int[] deliverableEvents;

    int[] inputEvents;

    int[] dontPropagateMask;

    InputClients inputClients;

    OtherInputMasks() {
        deliverableEvents = new int[9/* EMASKSIZE */];
        inputEvents = new int[9/* EMASKSIZE */];
        dontPropagateMask = new int[9/* EMASKSIZE */];
    }
}

class WindowOpt {
    int visual;

    Cursor cursor;

    Colormap colormap;

    int dontPropagateMask;

    int otherEventMasks;

    OtherClients otherClients;

    Grab passiveGrabs;

    Property userProps;

    long backingBitPlanes;

    long backingPixel;

    OtherInputMasks otherInputMasks;

    java.awt.Window frame;
}

class Sprite {
    Window win;

    HotSpot hot;

    Sprite() {
        hot = new HotSpot();
    }
}

final class HotSpot extends Point {
    int state = 0;
}

class DontPropagate {
    static int[] masks = new int[8];

    static int[] refc = new int[8];
    static {
        for (int i = 0; i < 8; i++) {
            masks[i] = refc[i] = 0;
        }
    }

    static int store(int mask) {
        int i = 0;
        int free = 0;
        for (i = 8, free = 0; --i > 0;) {
            if (refc[i] == 0) {
                free = i;
            } else if (mask == masks[i])
                break;
        }
        if (i == 0 && free != 0) {
            i = free;
            masks[i] = mask;
        }
        return i;
    }
}

class Focus {
    int win;

    Window window;

    int revert;

    long time;

    Window[] trace;

    int traceSize;

    int traceGood;
}
